代理模式与装饰模式的异同

代理模式和装饰模式有很大的相似之处,看代理模式的类图,可以看做是代理模式的类图,也可以看做是装饰模式的类图,因为他们之间太像了,像到什么程度?把实现的代码改一下就是装饰模式,改回来就是代理模式。

追美女的一种方式是从她的朋友下手,让她的死党帮忙,那就离成功没有多远了。好,我们把她的死党作为这个美女的代理,开始的时候我们当然要和代理打交道了,我们用代理模式实现以下。定义一个接口,这个借口有一个behavior()方法。

  1. 1.public interface Girl {    
  2. 2.        
  3. 3.    public void behavior();    
  4. 4.   
  5. 5.}   
1.public interface Girl {   
2.       
3.    public void behavior();   
4.  
5.}  


然后让美女类实现这个接口

  1. 1.public class NiceGirl implements Girl {    
  2. 2.   
  3. 3.    private String name;    
  4. 4.    public NiceGirl(String name){    
  5. 5.        this.name = name;    
  6. 6.    }    
  7. 7.    @Override   
  8. 8.    public void behavior() {    
  9. 9.        System.out.println(this.name+"长的非常nice");    
  10. 10.        System.out.println(this.name+"说话也非常nice");    
  11. 11.   
  12. 12.    }    
  13. 13.   
  14. 14.}   
1.public class NiceGirl implements Girl {   
2.  
3.    private String name;   
4.    public NiceGirl(String name){   
5.        this.name = name;   
6.    }   
7.    @Override  
8.    public void behavior() {   
9.        System.out.println(this.name+"长的非常nice");   
10.        System.out.println(this.name+"说话也非常nice");   
11.  
12.    }   
13.  
14.}  


接下来定义代理类,代理类也实现了Girl接口,不但如此,代理类还要关联它要代理的对象,所以要定义Girl类型的一个成员变量,

  1. 1.import java.util.Random;    
  2. 2.   
  3. 3.public class GirlAgent implements Girl {    
  4. 4.        
  5. 5.    private Girl girl;    
  6. 6.   
  7. 7.    public GirlAgent(Girl girl) {    
  8. 8.        super();    
  9. 9.        this.girl = girl;    
  10. 10.    }    
  11. 11.   
  12. 12.    @Override   
  13. 13.    public void behavior() {    
  14. 14.        Random rand = new Random();    
  15. 15.        if(rand.nextBoolean())    
  16. 16.        {    
  17. 17.            System.out.println("我安排你们上自习");    
  18. 18.            girl.behavior();    
  19. 19.        }    
  20. 20.        else{    
  21. 21.            System.out.println("先看你的表现,上自习以后再说");    
  22. 22.        }    
  23. 23.    }    
  24. 24.}   
1.import java.util.Random;   
2.  
3.public class GirlAgent implements Girl {   
4.       
5.    private Girl girl;   
6.  
7.    public GirlAgent(Girl girl) {   
8.        super();   
9.        this.girl = girl;   
10.    }   
11.  
12.    @Override  
13.    public void behavior() {   
14.        Random rand = new Random();   
15.        if(rand.nextBoolean())   
16.        {   
17.            System.out.println("我安排你们上自习");   
18.            girl.behavior();   
19.        }   
20.        else{   
21.            System.out.println("先看你的表现,上自习以后再说");   
22.        }   
23.    }   
24.}  


OK,代理类图中的所有的类都实现了,下面编写一个测试类

  1. 1.public class Client {    
  2. 2.   
  3. 3.    public static void main(String[] args) {    
  4. 4.            
  5. 5.      Girl niceGirl = new NiceGirl("小美");    
  6. 6.   
  7. 7.      Girl friend = new GirlAgent(niceGirl);    
  8. 8.          
  9. 9.      friend.behavior();    
  10. 10.    }    
  11. 11.   
  12. 12.}   
1.public class Client {   
2.  
3.    public static void main(String[] args) {   
4.           
5.      Girl niceGirl = new NiceGirl("小美");   
6.  
7.      Girl friend = new GirlAgent(niceGirl);   
8.         
9.      friend.behavior();   
10.    }   
11.  
12.}  


哈哈,代理模式就学会了吧。那装饰模式是怎么回事呢?装饰模式只要改动一处代码就可以了,对代理类的behavior()方法改动如下,其他的类不用动。

  1.      @Override   
  2. 2.       public void behavior() {    
  3. 3.   
  4. 4.System.out.println("我家MM不但知书达礼,而且还会做饭");    
  5. 5.girl.behavior();    
  6. 6.   
  7. 7.        }   
     @Override  
2.       public void behavior() {   
3.  
4.System.out.println("我家MM不但知书达礼,而且还会做饭");   
5.girl.behavior();   
6.  
7.        }  


看出却别来了吗?只是代理类(或者说装饰类)的实现方法不同。

代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能,仅此而已。

什么情况下用代理模式什么情况下用装饰模式呢?那就得看情况了,如果是为了给对象增加功能,那就用装饰模式。比如一个Plane类它的fly()方法中飞行速度是300m/s,那能不能实现500m/s的飞机对象呢?有装饰模式就可以实现。700m/s的呢?呵呵,装饰两次就行了。不是定义两个装饰器类,而是定义一个装饰器能够增速200m/s,然后装饰两次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值