java代理模式:深入浅出基于Java的代理设计模式

、引子   我们去科技市场为自己机器添加点奢侈配件很多DIYer都喜欢去找代理商在代理商那里拿到东西不仅质量有保证而且价格和售后服务上都会好很多客户通过代理商得到了自己想要东西而且还享受到了代理商额外服务;而生产厂商通过代理商将自己产品推广出去而且可以将些销售服务任务交给代理商来完成(当然代理商要和厂商来共同分担风险分配利润)这样自己就可以花更多心思在产品设计和生产上了   在美国任何企业产品要想拿到市场上去卖就必须经过代理商这个环节否则就是非法看来代理商在商业运作中起着很关键作用 不小心把话题扯远了回过头来那么在我们面向对象设计中会不会有代理商这样角色呢?来看这篇文章人肯定不会说:没有!   那么就跟着这篇文章来看看代理模式奇妙吧    2、定义和分类   代理模式在设计模式中定义就是:为其他对象提供种代理以控制对这个对象访问说白了就是些情况下客户不想或者不能直接引用个对象而代理对象可以在客户和目标对象的间起到中介作用去掉客户不能看到内容和服务或者增添客户需要额外服务   那么什么时候要使用代理模式呢?在对已有思路方法进行使用时候出现需要对原有思路方法进行改进或者修改这时候有两种改进选择:修改原有思路方法来适应现在使用方式或者使用个“第 3者”思路方法来原有思路方法并且对思路方法产生结果进行控制种思路方法是明显违背了“对扩展开放、对修改关闭”(开闭原则)而且在原来思路方法中作修改可能使得原来类功能变得模糊和多元化(就像现在企业多元化样)而使用第 2种方式可以将功能划分更加清晰有助于后面维护所以在定程度上第 2种方式是个比较好选择!   当然话又说回来了如果是个很小系统功能也不是很繁杂那么使用代理模式可能就显得臃肿不如第种方式来快捷这就像个 3口的家家务活全由家庭主妇或者个保姆来完成是比较合理根本不需要雇上好几个保姆层层代理:)   根据Java和模式书中对代理模式分类代理模式分为8种这里将几种常见、重要列举如下:   1. 远程(Remote)代理:为个位于区别地址空间对象提供个局域代表对象比如:你可以将个在世界某个角落台机器通过代理假象成你局域网中部分   2. 虚拟(Virtual)代理:根据需要将个资源消耗很大或者比较复杂对象延迟真正需要时才创建比如:如果个很大图片需要花费很长时间才能显示出来那么当这个图片包含在文档中时使用编辑器或浏览器打开这个文档这个大图片可能就影响了文档阅读这时需要做个图片Proxy来代替真正图片   3. 保护(Protect or Access)代理:控制对个对象访问权限比如:在论坛中区别身份登陆拥有权限是区别使用代理模式可以控制权限(当然使用别方式也可以实现)   4. 智能引用(Smart Reference)代理:提供比对目标对象额外服务比如:纪录访问流量(这是个再简单不过例子)提供些友情提示等等   代理模式是种比较有用模式从几个类“小结构”到庞大系统“大结构”都可以看到它影子    3、结构   代理模式中“代理商”要想实现代理任务就必须和被代理“厂商”使用共同接口(你可以想象为产品)所以自然而然你会想到在java中使用个抽象类或者接口(推荐)来实现这个共同接口于是代理模式就有 3个角色组成了:   1.抽象主题角色:声明了真实主题和代理主题共同接口   2.代理主题角色:内部包含对真实主题引用并且提供和真实主题角色相同接口   3.真实主题角色:定义真实对象   使用类图来表示下 3者间关系如下: 当然图上所示是代理模式中个具体情况而代理模式可以非常灵活使用其他方式来实现这样就和图上所示有很大区别   也许现在你已经对代理模式已经有了个宏观认识了下面我们来看看如何实际使用代理模式    4、举例   以论坛中已注册用户和游客权限区别来作为第个例子:已注册用户拥有发帖修改自己注册信息修改自己帖子等功能;而游客只能看到别人发帖子没有其他权限为了简化代码更好显示出代理模式骨架我们这里只实现发帖权限控制 首先我们先实现个抽象主题角色MyForum里面定义了真实主题和代理主题共同接口——发帖功能   代码如下: public erface MyForum { public void AddFile; }   这样真实主题角色和代理主题角色都要实现这个接口其中真实主题角色基本就是将这个接口思路方法内容填充进来所以在这里就不再赘述它实现我们把主要精力放到关键代理主题角色上代理主题角色代码大体如下: public MyForumProxy implements MyForum {  private RealMyForum forum ;  private permission ; //权限值  public MyForumProxy( permission)  {   forum = RealMyForum   this.permission = permission ;  }  //实现接口  public void AddFile  {   //满足权限设置时候才能够执行操作   //Constants是个常量类   (Constants.ASSOCIATOR permission)   {    forum.AddFile;   }       .out.prln("You are not a associator of MyForum ,please registe!");  } }   这样就实现了代理模式功能当然你也可以在这个代理类上添加自己思路方法来实现额外服务比如统计帖子浏览次数记录用户登录情况等等   还有个很常见代理模式使用例子就是对大幅图片浏览控制在我们常见网站WebSite上面浏览图文信息时不知道你有没有注意到图片位置放置是经过缩小当有人要仔细查看这个图片时可以通过点击图片来激活个链接个新网页打开要看图片 这样对于提高浏览速度是很有好处不是每个人都要去看仔细图上信息这种情况就可以使用代理模式来全面实现这里我将思路表述出来至于实现由于工作原因就不表述了至于这种方式在B/S模式下真实可行性我没有确认过只是凭空想象如果不是可行方式那这个例子可以放到个C/S下来实现这个是绝对没有问题而且在很多介绍设计模式书和文章中使用两种方式实现有兴趣可以来尝试   我们在浏览器中访问网页时是不是真实装载图片思路方法而是在代理对象中思路方法在这个对象中先使用个线程向浏览器装载了个缩小版图片而在后台使用另个线程来真实装载大图片思路方法将图片加载到本地当你要浏览这个图片时候将其在新网页中显示出来当然如果在你想浏览时候图片尚未加载成功可以再启动个线程来显示提示信息直到加载成功   这样代理模式功能就在上面体现淋漓尽致——通过代理来将真实图片加载放到后台来操作使其不影响前台浏览    5、整理总结   代理模式能够协调者和被能够在定程度上降低系统耦合度不过定要记住前面讲使用代理模式条件不然话使用了代理模式不但不会有好效果说不定还会出问题
Tags:  java的设计模式 java与设计模式 java设计模式 java代理模式

延伸阅读

最新评论

发表评论