
主要讲解代理模式的实现方式基于java。这个是目前设计模式的最后一篇文章后面如果项目中用到其它的设计模式会结合具体的实例然后继续连载。前言首先了解一下代理模式的定义。为其他对象提供一种代理以控制这个对象的访问。涉及角色及说明Subject抽象主题类接口或者抽象类声明真实主题与代理的共同接口方法。RealSubject真实主题类也叫做被代理类或被委托类定义了代理所表示的真实对象负责具体业务逻辑的执行客户端可以通过代理类间接的调用真实主题类的方法。Proxy代理类也叫委托类持有对真实主题类的引用在其所实现的接口方法中调用真实主题类中相应的接口方法执行。Client客户端类使用代理模式的地方。理解代理模式属于结构型模式。代理模式也叫委托模式。生活中比如代购、打官司等等实际上都是一种代理模式。代理模式可以分为静态代理和动态代理。静态代理创建抽象主题public interface penguin { public void beating(); }创建真实主题public class littlePenguin implements penguin { Override public void beating() { System.out.println(打豆豆); } }创建静态代理类public class penguinProxy { private penguin m_penguin; public penguinProxy(penguin p) { this.m_penguin p; } public void beating() { System.out.println(打豆豆前); m_penguin.beating(); System.out.println(打豆豆后); } }使用姿势public static void main(String args[]) { penguin penguin1 new littlePenguin(); penguinProxy proxy new penguinProxy(penguin1); proxy.beating(); }输出打豆豆前 打豆豆 打豆豆后静态代理很简单就是不直接调用littlePenguin中的方法都是通过代理类来处理。这个示例是我参考网上写的不过我觉得这个示例有一个问题就是在main()中先new一个littlePenguin然后赋值给代理类penguinProxy我觉得如果需要对littlePenguin完全进行封装就应该在代理类中搞一个littlePenguin单例因为对littlePenguin的使用不应该暴露到main中要不然搞这个代理就没有太大意义当然这个只是我的个人理解哈。动态代理创建动态代理类public class penguinProxy implements InvocationHandler { private Object obj; // 被代理的对象 public penguinProxy(Object obj) { this.obj obj; } Override public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { System.out.println(海外动态代理调用方法: method.getName()); Object result method.invoke(obj, args); return result; } }使用姿势public static void main(String args[]) { penguin penguin1 new littlePenguin(); // 创建动态代理 penguinProxy proxy new penguinProxy(penguin1); //获取ClassLoader ClassLoader loader penguin1.getClass().getClassLoader(); //通过Proxy创建代理实例实际上通过反射来实现的 penguin penguin2 (penguin) Proxy.newProxyInstance(loader, new Class[]{penguin.class}, proxy); penguin2.beating(); }输出海外动态代理调用方法:beating 打豆豆动态代理的方式很灵活后面会在剖析两者的区别。从个人理解这个应该只有java才能使用这种动态代理的方式吧不知道PHP和Go是否可以支持欢迎大家一起讨论哈~~静态代理 VS 动态代理静态代理的缺点静态代理如果接口新增一个方法除了所有实现类真实主题类需要实现这个方法外所有代理类也需要实现此方法。增加了代码维护的复杂度。代理对象只服务于一种类型的对象如果要服务多类型的对象。必须要为每一种对象都进行代理静态代理在程序规模稍大时就无法胜任了。动态代理的优点可以通过一个代理类完成全部的代理功能接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。当接口方法数量较多时我们可以进行灵活处理而不需要像静态代理那样每一个方法进行中转。动态代理的应用使我们的类职责更加单一复用性更强。动态代理的缺点不能对类进行代理只能对接口进行代理如果我们的类没有实现任何接口那么就不能使用这种方式进行动态代理因为$Proxy()这个类集成了Proxy,Java的集成不允许出现多个父类。优缺点分析优点代理作为调用者和真实主题的中间层,降低了模块间和系统的耦合性。可以以一个小对象代理一个大对象,达到优化系统提高运行速度的目的。代理对象能够控制调用者的访问权限起到了保护真实主题的作用。缺点由于在调用者和真实主题之间增加了代理对象因此可能会造成请求的处理速度变慢。实现代理模式需要额外的工作有些代理模式的实现非常复杂从而增加了系统实现的复杂度。适用场景当一个对象不能或者不想直接访问另一个对象时可以通过一个代理对象来间接访问。为保证客户端使用的透明性委托对象和代理对象要实现同样的接口。被访问的对象不想暴露全部内容时可以通过代理去掉不想被访问的内容。根据适用范围代理模式可以分为以下几种远程代理为一个对象在不同的地址空间提供局部代表这样系统可以将Server部分的事项隐藏。虚拟代理如果要创建一个资源消耗较大的对象可以先用一个代理对象表示在真正需要的时候才真正创建。保护代理用代理对象控制对一个对象的访问给不同的用户提供不同的访问权限。智能引用在引用原始对象的时候附加额外操作并对指向原始对象的引用增加引用计数。