定义
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
UML
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。(最简单的比如打印日志)
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
实例
代理商,本身不生成产品,但是从厂家拿产品卖个用户。起到媒介作用。
java的代理模式
简单demo:
扫描二维码关注公众号,回复:
849979 查看本文章
/** * 抽象主题,定义主要功能 */ publicinterface Subject { publicvoid operate(); } /** * 具体主题 */ publicclass RealSubject implements Subject{ @Override publicvoid operate() { System.out.println("realsubject operatestarted......"); } } /** * 代理类 */ publicclass Proxy implements Subject{ private Subject subject; public Proxy(Subject subject) { this.subject = subject; } @Override publicvoid operate() { System.out.println("before operate......"); subject.operate(); System.out.println("after operate......"); } } public class Client { publicstaticvoid main(String[] args) { Subject subject = new RealSubject(); Proxy proxy = new Proxy(subject); proxy.operate(); } }
动态代理
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.lang.reflect.Method; //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类 interface BusinessFoo { void foo(); } interface BusinessBar { String bar(String message); } //真实角色:真正实现业务逻辑方法 class BusinessFooImpl implements BusinessFoo { public void foo() { System.out.println("BusinessFooImpl.foo()"); } } class BusinessBarImpl implements BusinessBar { public String bar(String message) { System.out.println("BusinessBarImpl.bar()"); return message; } } //动态角色:动态生成代理类 class BusinessImplProxy implements InvocationHandler { private Object obj; BusinessImplProxy() { } BusinessImplProxy(Object obj) { this.obj = obj; } public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object result = null; doBefore(); result = method.invoke(obj,args); doAfter(); return result; } public void doBefore(){ System.out.println("do something before Business Logic"); } public void doAfter(){ System.out.println("do something after Business Logic"); } public static Object factory(Object obj) { Class cls = obj.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj)); } } //测试类 public class DynamicProxy { public static void main(String[] args) throws Throwable { BusinessFooImpl bfoo = new BusinessFooImpl(); BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo); bf.foo(); System.out.println(); BusinessBarImpl bbar = new BusinessBarImpl(); BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar); String message = bb.bar("Hello,World"); System.out.println(message); } }
优点
(1).职责清晰真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
(3).高扩展性
比较
代理模式与外观模式的区别:
1、外观模式也是屏蔽复杂性的,但是外观模式不会实现客户端调用的目标类型接口。
2、一般客户端调用外观模式的方法都是直接调用。
3、代理模式中对客户端目标对象类型抽象接口具体化了。
4、外观模式是代理模式中一种特殊的子级模式(广泛的,非约束性)。
代理模式与适配器模式区别
适配器为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,
因此,它的接口实际上可能只是实体接口的一个子集。
代理模式与装饰器模式区别
尽管装饰器的实现部分与代理相似,但装饰器的目的不一样。装饰器为对象添加一个或多个功能,而代理则控制对对象的访问。