您现在的位置是:首页 > 文章详情

JAVA中的设计模式四(装饰模式)

日期:2018-05-31点击:375

-------装饰模式

装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

-------1.介绍

意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

何时使用:在不想增加很多子类的情况下扩展类。

如何解决:将具体功能职责划分,同时继承装饰者模式。

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

应用实例: 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承。

-------2.实例

2.1把一个形状装饰上不同的颜色,同时又不改变形状类

2.1.1.我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。

2.1.2.RedShapeDecorator 是实现了 ShapeDecorator 的实体类。

2.1.3.test,我们的演示类使用 RedShapeDecorator 来装饰 Shape 对象。

 1 package decorate;  2  3 /**  4  * @author Administrator  5  * 形状接口  6 */  7 public interface Shape {  8 void draw();  9 } 10 11 12 13 package decorate; 14 15 /** 16  * @author Administrator 17  *长方形 18 */ 19 public class Rectangle implements Shape { 20 21  @Override 22 public void draw() { 23 // TODO Auto-generated method stub 24 System.out.println("形状:长方形"); 25  } 26 27 28 } 29 30 31 32 33 34 package decorate; 35 36 /** 37  * @author Administrator 38  *圆形 39 */ 40 public class Circle implements Shape { 41 42  @Override 43 public void draw() { 44 // TODO Auto-generated method stub 45 System.out.println("形状:圆形"); 46  } 47 48 49 } 50 51 52 53 54 package decorate; 55 56 /** 57  * @author Administrator 58  * 装饰对象 59 */ 60 public abstract class ShapeDecorator implements Shape {//装饰器 61 protected Shape decoratedShape; 62  @Override 63 public void draw() { 64 // TODO Auto-generated method stub 65  decoratedShape.draw(); 66  } 67 public ShapeDecorator(Shape decoratedShape) { 68 this.decoratedShape = decoratedShape; 69  } 70 71 72 }

 

 

 1 package decorate;  2  3 /**  4  * @author Administrator  5  * 颜色 红色  6 */  7 public class RedShapeDecorator extends ShapeDecorator {  8  9 public RedShapeDecorator(Shape decoratedShape) { 10 super(decoratedShape); 11 // TODO Auto-generated constructor stub 12  } 13 14  @Override 15 public void draw() { 16 // TODO Auto-generated method stub 17  decoratedShape.draw(); 18  setRedBorder(decoratedShape); 19  } 20 21 public void setRedBorder(Shape decoratedShape){ 22 System.out.println("颜色: Red"); 23  } 24 25 }

 

 

 1 package decorate;  2  3 public class Test {  4 public static void main(String[] args) {  5 Shape shape=new Circle();  6 Shape redCircle=new RedShapeDecorator(new Circle());  7  shape.draw();  8  System.out.println();  9  redCircle.draw(); 10  } 11 }

 

  输出结果:

形状:圆形

形状:圆形
颜色: Red

 

2.2.装饰模式为已有类动态附加额外的功能就像LOL英雄升级一样。每次英雄升级都会附加一个额外技能点学习技能。

 1 package lol;  2  3 /**  4  * @author GH  5  * 英雄接口  6 */  7 public interface Hero {  8 void study();  9 }  10  11  12  13 package lol;  14  15 /**  16  * @author GH  17  * 具体的英雄 蛮王  18 */  19 public class BarbarianKing implements Hero {  20 private String name;  21  @Override  22 public void study() {  23 // TODO Auto-generated method stub  24 System.out.println("英雄:"+name);  25  }  26 public BarbarianKing(String name) {  27 super();  28 this.name = name;  29  }  30  31 }  32  33  34  35 package lol;  36  37 /**  38  * @author Administrator  39  * 技能装饰器  40 */  41 public abstract class Skills implements Hero{  42 protected Hero heroSkill;  43  44 public Skills(Hero heroSkill) {  45 this.heroSkill = heroSkill;  46  }  47  @Override  48 public void study() {  49 // TODO Auto-generated method stub  50  heroSkill.study();  51  }  52 }  53  54  55  56 package lol;  57  58 /**  59  * @author Administrator  60  *具体技能Q  61 */  62 public class KillQ extends Skills {  63  64 public KillQ(Hero heroSkill) {  65 super(heroSkill);  66 // TODO Auto-generated constructor stub  67  }  68  69  @Override  70 public void study() {  71 // TODO Auto-generated method stub  72  heroSkill.study();  73  setkill(heroSkill);  74  }  75 public void setkill(Hero hero){  76 System.out.println("习得技能:Q");  77  }  78  79 }  80  81  82  83 package lol;  84  85 /**  86  * @author Administrator  87  *具体技能W  88 */  89 public class KillW extends Skills {  90  91 public KillW(Hero heroSkill) {  92 super(heroSkill);  93 // TODO Auto-generated constructor stub  94  }  95  96  @Override  97 public void study() {  98 // TODO Auto-generated method stub  99  heroSkill.study(); 100  setkill(heroSkill); 101  } 102 public void setkill(Hero hero){ 103 System.out.println("习得技能:W"); 104  } 105 106 } 107 108 109 package lol; 110 111 public class Test { 112 113 public static void main(String[] args) { 114 // TODO Auto-generated method stub 115 Hero hero=new BarbarianKing("蛮王"); 116  hero.study(); 117  System.out.println(); 118 KillQ q=new KillQ(hero); 119  q.study(); 120 121  System.out.println(); 122 KillQ q2=new KillQ(q); 123  q2.study(); 124 125  System.out.println(); 126 KillW w=new KillW(q2); 127  w.study(); 128  } 129 130 }

 

  输出结果:

英雄:蛮王

英雄:蛮王
习得技能:Q

英雄:蛮王
习得技能:Q
习得技能:Q

英雄:蛮王
习得技能:Q
习得技能:Q
习得技能:W

-------3.总结:

  装饰模式是为已有功能动态的添加更多功能的一种方式。当系统需要新功能的时候,通过新加代码来装饰原有类的核心职责,而这些新加的东西仅仅是为了满足一些只在特殊情况下才会执行的特殊行为。装饰模式的有点其实就是:把类中装饰功能从类中搬除出去,在简化原有类的基础上有效的把类的核心职责和装饰功能区分开来。

欢迎大家一起说出自己的想法。
原文链接:https://yq.aliyun.com/articles/643537
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章