设计模式学习之Decorator模式
继续学习设计模式,今天是装饰者模式,它属于结构型模式,首先还是它的基本概念:
- 装饰者模式:
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
- 适用性:
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 处理那些可以撤消的职责。
- 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
- 我的理解是:
装饰者模式就好比一个个wrapper(包装器),将一个对象一层层的包装,然后返回包装后的对象,就好比你在网上购买了一个电饭锅,那么这个电饭锅就是最原始的对象,而商家可能会在发货时进行一个初步包装,首先将电饭锅用一层泡沫包起来,然后装入一个纸箱,接着交给快递公司,然后快递公司收到这个物品后,还要进行二次包装,即使用快递公司专门的盒子装起来(或者用麻袋装好),然后贴上胶布开始运输,客户收到的这个箱子自后,一层层解开包装,最后拿出电饭锅。那么所有包装这个电饭锅的东西,像泡沫啊,纸箱啊,盒子啊,胶布啊,都可以算作装饰者,装饰者将原来的对象装饰完之后,会生成一个装饰后的对象,使源对象加上各种装饰品。所以,既然装饰者依赖于被装饰的对象,那么,装饰者在实现时就理所当然需要一个被装饰的对象的引用了,然后装饰完之后该引用就会指向装饰后的对象了。
所以,装饰者模式一定要搞明白装饰者的使用方式。 - 另外,因为装饰者能够替换源对象,所以在实际实现时需要将装饰者和源对象继承同一个父类(这个和实际有所不同,实际中,装饰者和源对象是不同的对象种类,但设计总归设计,不能总是和实际完美的相符,是需要一些灵活的处理的,而且这种设计的其本质是装饰者装饰之后的对象和源对象属于同一个父类,就好比电饭锅和装在盒子里的电饭锅都是电饭锅一样,但盒子并不是电饭锅)
- 还有一点就是,实际实现的装饰者,是装饰源对象的某个方法,相当于将被装饰的对象的某个方法增添或替换成某种方法而不改变源对象的代码和结构,就相当于动态的改变某种功能。
代码:
1 //被装饰者接口 2 public interface IProduct 3 { 4 public void transport(); 5 } 6 //具体的被装饰者 7 public class Product implements IProduct 8 { 9 protected String name; 10 public Product(String name) 11 { 12 this.name=name; 13 } 14 public void transport() 15 { 16 System.out.println("原始的产品:"+this.name); 17 System.out.println("运输..."); 18 } 19 } 20 //装饰者类 21 public class Decorator implements IProduct 22 { 23 protected IProduct product; 24 protected String name; 25 public Decorator(IProduct product, String name) 26 { 27 this.product=product; 28 this.name=name; 29 } 30 public void transport() 31 { 32 System.out.println("包装"); 33 if(this.product != NULL) 34 { 35 this.product.transport(); 36 } 37 } 38 } 39 //具体的装饰者1 40 public class Decorator1 extends Decorator 41 { 42 public void Decorator1(IProduct product) 43 { 44 this.product=product; 45 this.name="泡沫"; 46 } 47 public void transport() 48 { 49 System.out.println("用"+this.name+"包装"); 50 if(this.pruduct != NULL) 51 { 52 this.product.transport(); 53 } 54 } 55 } 56 //具体的装饰者2 57 public class Decorator2 extends Decorator 58 { 59 public void Decorator1(IProduct product) 60 { 61 this.product=product; 62 this.name="纸盒"; 63 } 64 public void transport() 65 { 66 System.out.println("用"+this.name+"包装"); 67 if(pruduct != NULL) 68 { 69 this.product.method1(); 70 } 71 } 72 } 73 public class Test 74 { 75 public static void main(String argv[]) 76 { 77 IProduct product=new Product("电饭锅"); 78 product=new Decorator1(product);//用泡沫包装 79 product=new Decorator2(product);//用纸盒包装 80 /*之后product对象就是被纸盒包装又被泡沫包装的对象了*/ 81 product.transport();//从外到里依次输出包装物直到原产品,最后进行运输 82 } 83 }
作者:everdom
出处:http://everdom.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。