package M_Proxy.b;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
/**
*代理模式:为另一个对象提供替身或占位符以控制对这个对象的访问
*
* 1:GumballMachineRemote
* 2:GumballMachine extends UnicastRemoteObject implementsGumballMachineRemote,
* 提供构造并throws RemoteException
* 3:State extends Serializable
* 4:State不序列化transient GumballMachine gumballMachine;
* 5:在bin目录下执行:rmic M_Proxy.b.GumballMachine
* 生成stub(客户端用)和skeleton(服务器用)
* 6:在Rmi registry注册
* rmiregistry
* java M_Proxy.b.GuamballMachineTestDrive
*
* 远程代理(代理远程服务):本地调用代理方法,代理通过网络转发到远程执行并获得结果给本地
* 虚拟代理(创建开销大的对象代表):虚拟对象在真正需要对象时,才创建对象,对象创建后将请求委托给对象
* 保护代理:控制对象访问
* 防火墙代理:控制网络资源的访问,保护主题免于坏客户的侵害
* 智能引用代理:主题被引用时,进行额外的动作,如计算对象被引用的次数
* 缓存代理:为开销大的运算结果提供暂时存储,也允许多个客户共享结果,减少网络延迟和计算(web服务器代理,内容管理与出版系统)
* 同步代理:在多线程的情况下为主题提供安全的访问,场景:javaspace
* 复杂隐藏代理:用来隐藏一个类的复杂集合的复杂度,并进行访问控制,也称为外观代理
* 写入时复制代理:用来控制对象的复制,方法是延迟对象的复制,直到客户真正需要的时候,虚拟代理变体(CopyOnWriteArrayList)
*
*
*/
public class GuamballMachineTestDrive {
public static void main(String[] args) {
int count = 0;
if (args.length < 2) {
System.out.println(“请输入ip地址和糖果数量”);
System.exit(1);
}
try {
count = Integer.parseInt(args[1]);
GumballMachineRemote gumballMachine = new GumballMachine(args[0], count);
//一定要这步注册端口
// rebind(//localhost:port/name,remoteObject);
LocateRegistry.createRegistry(6600);
Naming.rebind("//" + args[0] + ":6600/gumballMachine", gumballMachine);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package M_Proxy.b;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class GumballMachine extends UnicastRemoteObject implements
GumballMachineRemote {
State soldOutState;
State soldState;
State noQuarterState;
State hasQuarterState;
State winnerState;
State state = soldOutState;
String location;
int count;
public GumballMachine() throws RemoteException {
}
public GumballMachine(String location, int count) throws RemoteException {
this.location = location;
this.count = count;
soldOutState = new SoldOutState(this);
soldState = new SoldState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
winnerState = new WinnerState(this);
if (count > 0)
state = noQuarterState;
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
public void releaseBall() {
System.out.println("Sell a candy");
if (count != 0)
count--;
}
/**
* 补充糖果
*/
public void refill(int count) {
this.count = count;
state = noQuarterState;
}
// //
public void setState(State state) {
this.state = state;
}
public String getLocation() {
return location;
}
public State getSoldOutState() {
return soldOutState;
}
public State getSoldState() {
return soldState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public State getState() {
return state;
}
public Integer getCount() {
return count;
}
public State getWinnerState() {
return winnerState;
}
@Override
public String toString() {
return "GumballMachine [state=" + state + ", count=" + count + "]";
}
}
package M_Proxy.b;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface GumballMachineRemote extends Remote {
public Integer getCount() throws RemoteException;
public String getLocation() throws RemoteException;
public State getState() throws RemoteException;
}
package M_Proxy.b;
import java.rmi.RemoteException;
/**
* 糖果监视器
*/
public class GumballMonitor {
GumballMachineRemote machine;
public GumballMonitor(GumballMachineRemote machine) {
this.machine = machine;
}
public void report() {
try {
System.out.println(machine.getLocation());
System.out.println(machine.getCount());
System.out.println(machine.getState());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
package M_Proxy.b;
import java.rmi.Naming;
public class GumballMonitorTestDrive {
public static void main(String[] args) {
String[] location = { “//127.0.0.1:6600/gumballMachine” };
GumballMonitor[] monitor = new GumballMonitor[location.length];
try {
for (int i = 0; i < location.length; i++) {
GumballMachineRemote mechine = (GumballMachineRemote) Naming
.lookup(location[i]);
monitor[i] = new GumballMonitor(mechine);
}
} catch (Exception e) {
}
for (int i = 0; i < monitor.length; i++) {
monitor[i].report();
}
}
}
package M_Proxy.b;
import java.util.Random;
public class HasQuarterState implements State {
Random randomWinner = new Random(System.currentTimeMillis());
transient GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("已经投入过25分");
}
public void ejectQuarter() {
System.out.println("退25分");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void turnCrank() {
System.out.println("转动曲柄");
int winner = randomWinner.nextInt(10);
if (winner == 0 && gumballMachine.getCount() > 1) {
gumballMachine.setState(gumballMachine.getWinnerState());
} else {
gumballMachine.setState(gumballMachine.getSoldState());
}
}
public void dispense() {
System.out.println("没有糖果分配");
}
}
package M_Proxy.b;
public class NoQuarterState implements State {
//transient:不序列化这个对象
transient GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("投入25分");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
public void ejectQuarter() {
System.out.println("你需要投入25分");
}
public void turnCrank() {
System.out.println("没钱,无法售出");
}
public void dispense() {
System.out.println("你需要投入钱");
}
}
package M_Proxy.b;
public class SoldOutState implements State {
transient GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("糖果已售空");
}
public void ejectQuarter() {
System.out.println("糖果已售空");
}
public void turnCrank() {
System.out.println("糖果已售空");
}
public void dispense() {
System.out.println("糖果已售空");
}
}
package M_Proxy.b;
public class SoldState implements State {
transient GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("请等待正在出糖果");
}
public void ejectQuarter() {
System.out.println("对不起,正在转动曲柄");
}
public void turnCrank() {
System.out.println("不能转动2次曲柄");
}
public void dispense() {
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("糖果售空");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
package M_Proxy.b;
import java.io.Serializable;
public interface State extends Serializable {
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
}
package M_Proxy.b;
/**
* 10次抽中一次的游戏
*/
public class WinnerState implements State {
transient GumballMachine gumballMachine;
public WinnerState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
public void insertQuarter() {
System.out.println("请等待正在出糖果");
}
public void ejectQuarter() {
System.out.println("对不起,正在转动曲柄");
}
public void turnCrank() {
System.out.println("不能转动2次曲柄");
}
public void dispense() {
System.out.println("恭喜你获得2个糖果");
gumballMachine.releaseBall();
if (gumballMachine.getCount() == 0) {
gumballMachine.setState(gumballMachine.getSoldOutState());
} else {
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("糖果已售空");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
}