设计模式笔记(九)--状态模式、代理模式

状态模式(State Pattern)

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

简单点说,一个对象持有一个状态对象来表示自己现在的状态,当有行为(动作请求)时,该对象会委托给当前状态对象处理,因当前状态对象的不同会表现出不同的行为。所以它利用对象组合来引用不同的状态对象,在客户看来就像修改了对象一样。

设计模式笔记(九)--状态模式、代理模式_第1张图片

像Head First上说的,状态模式和策略模式是双胞胎,他们的类图是一样的,状态模式通过改变对象内部对象的状态来帮助对象控制自己的行为,而不是用一堆if/else语句。策略模式一般会在运行时为对象指定合适的实例化好的策略对象,是继承的弹性替代方案。

在具体使用中,我们的客户类要拥有各个状态的实例成员变量,并在构造器中初始化他们。还要有一个状态实例变量来表示自己当前的状态,根据情况初始化成适当的状态对象。此外还要有设置当前状态的getter/setter方法。每个具体状态类的构造器中要获得并保存客户实例,以便控制客户的状态改变。

代理模式(Proxy Pattern)

为另一个对象提供一个替身或占位符以控制对这个对象的访问。

设计模式笔记(九)--状态模式、代理模式_第2张图片

真正对象RealSubject和代理对象Proxy都实现了Subject接口,所以客户对待Proxy就像对待RealSubject一样了。

Proxy持有RealSubject的引用,甚至会负责RealSubject的创建和销毁。代理就是用来控制和管理对象的访问的。

远程代理控制访问远程的对象,虚拟代理控制访问开销大的对象,保护代理基于权限控制对资源的访问。

  • Java的RMI(Remote Method Invacation)远程方法调用:

    • 基于Socket通信。客户辅助对象:Stub(存根)。服务辅助对象:Skeleton(骨架)

    • 远程服务接口要实现java.rmi.Remote接口(表明该接口用来支持远程调用),其中的方法必须抛出RemoteException异常,客户必须意识到网络和I/O的风险。变量和返回值必须是原语(Primitive)或可序列化(Serializable)类型的,也就是说自己写的类必须实现Serializable接口

    • 远程服务实现类要扩展UnicastRemoteObject(导出一个远程对象,获得与该远程对象通信的存根)并实现远程服务接口,构造器需要抛RemoteException异常,但实现的方法不用

    • 用Naming.rebind("RemoteHello",myRemoteImpl);绑定到rmiregistry

    • 客户端取Stub对象:MyRemote myRemote = (MyRemote) Naming.lookup("rmi://127.0.0.1/RemoteHello");

    • 执行顺序:rmiregistry→java Server→java Client

  • 动态代理:可以实现InvocationHandler接口,通过Proxy.newProxyInstance动态创建代理类,并在invoke方法中控制对真正对象的访问。

你可能感兴趣的:(设计模式,状态模式)