设计模式(二)__装饰设计模式
今天呢,来给大家介绍一下装饰设计模式,java中IO就使用到了这个模式。
装饰设计模式,顾名思义,就是对一个功能进行装饰,就跟女人化妆一样,人还是本人,但是化了妆就变得比原来更漂亮了。
需求:当你有个功能是在N年前建立的,如今老大觉得功能不够用了,需要进行增强,那么怎么办呢?
解决:你就可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。如果这个功能写错了,又可以把自己写的功能去掉而不影响以前的功能,是不是很灵活啊。这个类就是装饰类。
装饰设计模式呢,主要是对一组类进行功能的增强。
那么什么时候会用到装饰模式呢?
1.需要扩展一个类的功能,或给一个类增加附加责任
2.需要动态的给一个对象增加功能,这些功能可以再动态的撤销
3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实
好了,上菜了。
(由于本人比较笨,想不出什么比较恰当的例子,这里就借鉴一下http://blog.csdn.net/furongkang/article/details/7214100中的例子。什么?你说我懒? 哼,好吧,我承认我懒。)
1 /* 2 3 我家里有两套房子:平房,楼房。 4 5 House 6 |--PingFang 7 |--LouFang 8 9 可是像我这么土豪,又具有强烈的文艺范,又有众多妻妾。。。 相信你已经感觉到了我的霸王之气。 10 所以: 11 1,对平房进行田园风光式的打造。 12 2,对楼房进行欧式风格的打造。 13 可以通过继承的方式来完成。 14 15 House 16 |--PingFang 17 |--TianYuanPingFang 18 |--LouFang 19 |--OuShiLouFang 20 21 */ 22 abstract class House { 23 abstract void show(); 24 } 25 26 class PingFang extends House { 27 public void show() { 28 System.out.println("平房"); 29 } 30 } 31 32 class TianYuanPingFang extends PingFang { 33 public void showTianYuan() { 34 super.show(); 35 System.out.println("田园风格"); 36 } 37 } 38 39 class LouFang extends House { 40 public void show() { 41 System.out.println("楼房"); 42 } 43 } 44 45 class OuShiLouFang extends LouFang { 46 public void showOuShi() { 47 super.show(); 48 System.out.println("欧式风格"); 49 } 50 } 51 52 class HouseDemo { 53 public static void main(String[] args) { 54 PingFang p = new PingFang(); 55 // p.show(); 56 57 TianYuanPingFang t = new TianYuanPingFang(); 58 t.showTianYuan(); 59 60 LouFang l = new LouFang(); 61 // l.show(); 62 OuShiLouFang o = new OuShiLouFang(); 63 o.showOuShi(); 64 } 65 }
上面的代码实现了我需要的功能,但是如果单单为了某个功能而去继承,那么那个体系是非常臃肿的。你说感觉不出来?假如你有几百个类,那么就会需要再写上几百个子类去继承。能累死个人。
装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。
装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
使用装饰设计模式进行装饰:
1 /* 2 原体系: 3 House 4 |--PingFang 5 |--LouFang 6 7 通过继承之后的体系 8 House 9 |--PingFang 10 |--TianYuanPingFang 11 |--LouFang 12 |--OuShiLouFang 13 14 无论将平房打造成田园还是欧式,都是对平房一种装修。 15 而该装修也可以用楼房。 16 17 将现将该装修定义好,需要把什么房子进行改装修,传入即可。 18 House 19 |--PingFang 20 |--LouFang 21 |--TianYuan 22 |--OuShi 23 24 */ 25 abstract class House { 26 abstract void show(); 27 } 28 29 class PingFang extends House { 30 public void show() { 31 System.out.println("平房"); 32 } 33 } 34 35 class LouFang extends House { 36 public void show() { 37 System.out.println("楼房"); 38 } 39 } 40 41 class TianYuan extends House { 42 43 private House h; 44 45 TianYuan(House h) { 46 this.h = h; 47 } 48 49 public void show() { 50 System.out.println("田园风格"); 51 } 52 53 public void showTianYuan() { 54 h.show(); 55 this.show(); 56 } 57 58 } 59 60 class OuShi extends House { 61 private House h; 62 63 OuShi(House h) { 64 this.h = h; 65 } 66 67 public void show() { 68 System.out.println("欧式风格"); 69 } 70 71 public void showOuShi() { 72 h.show(); 73 this.show(); 74 } 75 76 } 77 78 class HouseDemo2 { 79 public static void main(String[] args) { 80 PingFang p = new PingFang(); 81 LouFang l = new LouFang(); 82 83 OuShi o = new OuShi(new TianYuan(p)); 84 o.showOuShi(); 85 86 // TianYuan t = new TianYuan(l); 87 // t.showTianYuan(); 88 89 // OuShi o = new OuShi(l); 90 // o.showOuShi(); 91 } 92 }
是不是好了很多呢。