设计模式——代理模式与装饰模式的异同

两种模式的特点



装饰模式:

  在不改变接口的前提下,动态扩展对象的访问。
  动态继承,让类具有在运行期改变行为的能力。
  装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为。
  强调:增强

代理模式:

  在不改变接口的前提下,控制对象的访问。
  1.从封装的角度讲,是为了解决类与类之间相互调用而由此导致的耦合关系,可以说是接口的另外一个层引用。
    比如:在a类->b代理->c类这个关系中,c类的一切行为都隐藏在b中。即调用者不知道要访问的内容与代理了什么对象。
  2.从复用的角度讲,可以解决不同类调用一个复杂类时,仅仅因较小的改变而导致整个复杂类新建一个类。
    比如:a类->c类1;b类->c类2。
    可以变为a类->ca代理类->c类;b类->cb代理类-c类。
  代理模式,是类之间的封装和(某方面的)复用。
  强调:限制

举个例子说明问题



  下面通过一个例子来说明两者的不同。当我们冲咖啡的时候,首先你要拿咖啡粉冲好一杯咖啡,然后你可以考虑是否加方糖或牛奶。

  那么咖啡这个东西就可以通过糖或奶或者糖和奶,变成加糖的咖啡、加奶的咖啡、加糖加奶的咖啡。

  但是它还是一杯咖啡,只是它的属性进行了扩展。

  接下来分别通过装饰模式与代理模式,模拟这个过程。

1.装饰模式

  测试代码:

 1 Cafe cafe = new ConcreteCafe();
 2
 3 Cafe milkCafe = new MilkDecorator(cafe);
 4 milkCafe.getCafe();
 5 System.out.println("----------------------------------------");
 6 Cafe sugarCafe = new SugarDecorator(cafe);
 7 sugarCafe.getCafe();
 8 System.out.println("----------------------------------------");
 9 Cafe sugarMilkCafe = new MilkDecorator(new SugarDecorator(new ConcreteCafe()));
10 sugarMilkCafe.getCafe();
11 System.out.println("----------------------------------------");
12 Cafe milkSugarCafe = new SugarDecorator(new MilkDecorator(cafe));
13 milkSugarCafe.getCafe();
14 System.out.println("----------------------------------------");

  就像使用IO流一样:

1 BufferedReader in1 = new BufferedReader(new InputStreamReader(new FileInputStream(file)));//字符流
2 DataInputStream in2 = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));//字节流

  对类进行了功能的增强。

2.代理模式

  测试代码:

1 Cafe cafe = new Proxy();
2 cafe.getCafe();

现在可以很清楚的看到:

  1. 装饰模式可以让使用者直观的看到增强了哪些功能,而代理模式完全限制了使用者。

  2. 对装饰模式来说,装饰者(Decorator)和被装饰者(Cafe)都实现同一个 接口。

  3. 对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。

  4. 此外,不论我们使用哪一个模式,都可以很容易地在真实对象的方法前面或者后面加上自定义的方法。

装饰模式与继承的比较



  明显的,装饰模式可以动态的扩展对象的行为。

  比如某对象有30项行为,但是在第一阶段用到1-20行为,第二阶段用到11-30项行为,所以这时候,就可以只定义11-20的行为。

  在第一阶段运行时,可以将1-10的行为以“装饰1”给加上

  到第二阶段运行时,可以将“装饰1”去掉,将21-30的能以“装饰2”给加上。

  但是继承是在编译期增加行为。

装饰模式的优缺点



优点:

  1. 装饰模式可以提供比继承更多地灵活性。
  2. 可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
  3. 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
  4. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点:

  1. 会产生很多的小对象(具体装饰类),增加了系统的复杂性。
  2. 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

参考博文:

UML类图

修饰模式与代理模式的区别

设计模式之——装饰模式与代理模式的区别

Java之美——设计模式

装饰者模式

时间: 2024-10-05 12:26:35

设计模式——代理模式与装饰模式的异同的相关文章

代理模式 vs 装饰模式

代理模式和装饰模式有很大的相似性,二者的类图(几乎)是一样的.下面分别讲解代理模式和装饰模式. 1.代理模式 一般著名的跑步运动员都会有自己的代理人,如果想联系该运动员的比赛事宜,可以直接联系他的代理人就可以了.类图如下所示: IRunner接口如下: public interface IRunner { public void run(); } Runner类如下所示: public class Runner implements IRunner { @Override public void

【设计模式】代理模式和装饰模式之间的区别

学习了代理模式和装饰模式之后,对这两个的模式的区别产生了混淆,因为两个模式都是对一个类的功能进行扩充,而且服务类和客户类都同时实现了统一个接口. 那么,两者之间有什么区别呢? 通过http://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html的文章,总结得知,两种模式最大的不同就在于对于访问的控制,以及类之间关系的确定阶段的不同. 代理模式是在服务类中新建一个被代理类的实例,使用者得不到被代理类的具体信息,也无法访问,类似于中介对客

小菜学设计模式——代理模式

背景 很多时候,因为你的地位特殊而赋予你了不同的权限,那么你拥有别人做不到的事情.这个时候,如果你的朋友很想完成这样一件事情,但是她知道自己可能无法完成,但是你可以帮他处理,同时必要的话还可以中间拿点外快,不过最后要知道你是代理他完成这样一个事情,这就是代理模式出现的原因. 1.使用意图 通过代理角色代理真实角色去完成某一件特定事情,代理为什么会出现,因为代理身份的特殊性. 2.生活实例 找房子的时候会找代理,代理能够帮我找到房子,但是他额外收取了我一个月的房租,不说了,房租好贵! 3.Java

设计模式 - 代理模式(proxy pattern) 未使用代理模式 详解

代理模式(proxy pattern) 未使用代理模式 详解 本文地址: http://blog.csdn.net/caroline_wendy 部分代码参考: http://blog.csdn.net/caroline_wendy/article/details/37698747 如果需要监控(monitor)类的某些状态, 则需要编写一个监控类, 并同过监控类进行监控. 但仅仅局限于本地, 如果需要远程监控, 则需要使用代理模式(proxy pattern). 具体方法: 1. 类中需要提供

设计模式——代理模式

概念 代理模式(Proxy),为其他对象提供一种代理以控制对象的访问. 模式结构 一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再 访问真正要访问的对象. 代理模式UML图 代码实战 <span style="font-family:KaiTi_GB2312;font-size:18px;"> //代理模式 class  Proxy : IGiveGift                   //让"代理&qu

23种设计模式----------代理模式(二)

(上一篇)23种设计模式----------代理模式(一) 之前说了基本的代理模式和普通代理模式.接下来开始看下强制代理模式和虚拟代理模式 三,强制代理模式: 一般的代理模式都是通过代理类找到被代理的对象,从而调用被代理类中的方法(即完成被代理类中的任务). 而,强制代理模式则是先找到被代理类自己去完成事情,然后被代理类又将该做的事情转交到代理类中,让代理类来完成. 假如:你有事求助于某位名人. 你告诉名人说有事想请他帮忙,然后他说最近一段时间比较忙,要不你找我的经纪人来办吧. (本来找名人办事

23种设计模式----------代理模式(三) 之 动态代理模式

(上一篇)种设计模式----------代理模式(二) 当然代理模式中,用的最广泛的,用的最多的是  动态代理模式. 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理. 抽象接口的类图如下: --图来自设计模式之禅 所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类.其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理. 代码实现如下 抽象主题类或者接口: 1 package com.ye

23种设计模式----------代理模式(一)

代理模式也叫委托模式. 代理模式定义:对其他对象提供一种代理从而控制对这个对象的访问.就是,代理类 代理 被代理类,来执行被代理类里的方法. 一般情况下,代理模式化有三个角色. 1,抽象的主题类(或者接口) IGamePlayer 2,代理类. 3,被代理类. 下面以游戏玩家代理为例. 一,先来看下最基本的代理模式. 代码如下: 主题接口: 1 package com.yemaozi.proxy.base; 2 3 //游戏玩家主题接口 4 public interface IGamePlaye

5.大话设计模式-代理模式

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel { public class Proxy:IAction { ZQZ zzz = null; public Proxy(ZQZ mm) { zzz = mm; } public void SendFlower() { zzz