设计模式之装饰器模式

装饰器模式又叫包装器模式,用于动态的给一个对象增加一些额外的职能,取代一些情况下的继承的使用,增加灵活性。

     装饰器模式主要有一下部分组成:
      1)  抽象构件角色(  Component ):定义一个抽象接口,以规范准备接收附加责任的对象。
      2)  具体构件角色  (Concrete Component) :这是被装饰者,定义一个将要被装饰增加功能的 类。
      3)  装饰角色 (Decorator)  :持有一个构件对象的实例,并定义了抽象构件定义的接口。
      4)  具体装饰角色  (Concrete Decorator) :负责给构件添加增加的功能。
     应用的场景类似于:你的电脑内存只有2G,但是你想有一台内存是4G的电脑,你是选择加根内存条,还是买一台4G的电脑。又如果你的电脑没有无线网卡,你想有一台有无线网卡的电脑,你是去买个无线网卡插上,还是去买台有无线网卡的电脑。如果你的选择是买,那么当你在出现多个需求的时候,你可能买了很多台电脑了,明显这是没有必要的。你只需要的缺什么就往原来的电脑上加什么就可以了(当然是在兼容的情况下)。这就类似于一类的东西需要添加一个属性或功能,你是选择继承产生新的子类还是选择装饰器模式添加新的功能。
     下面的例子演示这种情况。
1 package com.cnblogs.ipolaris.Decorator.test;
2 
3 public interface Computer {
4         public void say();
5         public void describe();
6 }

 

 

 1 package com.cnblogs.ipolaris.Decorator.test;
 2 
 3 public class CommonComputer implements Computer {
 4 
 5         @Override
 6         public void say() {
 7                this .describe();
 8        }
 9 
10         @Override
11         public void describe() {
12               System. out .println("我是一台2G无网卡的电脑" );
13        }
14 
15 }

 

 1 package com.cnblogs.ipolaris.Decorator.test;
 2 
 3 public abstract class ComputerDecorator implements Computer {
 4        
 5         private Computer computer ;
 6        
 7         public ComputerDecorator(Computer computer){
 8                this .computer = computer;
 9        }
10        
11         public Computer getComputer() {
12                return computer ;
13        }
14 
15 
16         public void setComputer(Computer computer) {
17                this .computer = computer;
18        }
19 
20 
21        
22         public abstract void say() ;
23 
24 }

 

 1 package com.cnblogs.ipolaris.Decorator.test;
 2 
 3 public class AddMeComputer extends ComputerDecorator {
 4 
 5         public AddMeComputer(Computer computer) {
 6                super (computer);
 7                // TODO Auto-generated constructor stub
 8        }
 9 
10         @Override
11         public void describe() {
12               
13               System. out .println("增加了2G内存,升级为4G" );
14        }
15 
16         @Override
17         public void say() {
18                this .getComputer().say();
19                this .describe();
20        }
21 
22 }

 

 1 package com.cnblogs.ipolaris.Decorator.test;
 2 
 3 public class AddWifiComputer extends ComputerDecorator {
 4 
 5         public AddWifiComputer(Computer computer) {
 6                super (computer);
 7                // TODO Auto-generated constructor stub
 8        }
 9 
10         @Override
11         public void say() {
12                this .getComputer().say();
13                this .describe();
14 
15        }
16 
17         @Override
18         public void describe() {
19               System. out .println("我增加了无线模块" );
20 
21        }
22 
23 }

 

 1 package com.cnblogs.ipolaris.Decorator.test;
 2 
 3 public class Test {
 4 
 5         /**
 6         * @param args
 7         */
 8         public static void main(String[] args) {
 9               System. out .println("**************当前电脑*************" );
10               Computer computer = new CommonComputer();
11               computer.say();
12               System. out .println("**************只加内存的电脑*************" );
13               computer = new AddMeComputer(computer);
14               computer.say();
15               System. out .println("**************加了内存后加网卡的电脑*************" );
16               computer = new AddWifiComputer(computer);
17               computer.say();
18               
19        }
20 
21 }

运行结果

**************当前电脑*************
我是一台2G无网卡的电脑
**************只加内存的电脑*************
我是一台2G无网卡的电脑
增加了2G内存,升级为4G
**************加了内存后加网卡的电脑*************
我是一台2G无网卡的电脑
增加了2G内存,升级为4G
我增加了无线模块

当你想单独的添加无线模块式,只要删除

computer = new AddMeComputer(computer);

即可。
直观上来说,如果用继承,实现单独添加内存,单独添加无线模块,同时添加内存和无线模块,至少要三个子类,而这里是装饰器只要对应每个功能即可,可以以各种方式组合起来,不需要添加新的子类

转载于:https://www.cnblogs.com/ipolaris/archive/2012/09/13/2684144.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值