博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA中的设计模式四(装饰模式)
阅读量:4610 次
发布时间:2019-06-09

本文共 5817 字,大约阅读时间需要 19 分钟。

-------装饰模式

  装饰模式(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 Administrator17  *长方形18  */19 public class Rectangle implements Shape {20 21     @Override22     public void draw() {23         // TODO Auto-generated method stub24         System.out.println("形状:长方形");25     }26 27     28 }29 30 31 32 33 34 package decorate;35 36 /**37  * @author Administrator38  *圆形39  */40 public class Circle implements Shape {41 42     @Override43     public void draw() {44         // TODO Auto-generated method stub45         System.out.println("形状:圆形");46     }47 48     49 }50 51 52 53 54 package decorate;55 56 /**57  * @author Administrator58  *    装饰对象59  */60 public abstract class ShapeDecorator implements Shape {
//装饰器61 protected Shape decoratedShape;62 @Override63 public void draw() {64 // TODO Auto-generated method stub65 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 stub12     }13 14     @Override15     public void draw() {16         // TODO Auto-generated method stub17         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 stub115         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://www.cnblogs.com/GH0522/p/9122443.html

你可能感兴趣的文章
创建对象方法
查看>>
strrchr函数
查看>>
在.NET/Mono上运行Java:Jeroens Frijters谈IKVM.NET
查看>>
Spring for Apache Hadoop 1.0 RC1 发布
查看>>
DOC常用命令(转)
查看>>
php写一个判断是否有cookie的脚本
查看>>
Mac配置Fiddler抓包工具
查看>>
转:Java并发集合
查看>>
Word截图PNG,并压缩图片大小
查看>>
Python项目对接CAS方案
查看>>
mysql产生随机数
查看>>
编程风格
查看>>
熟悉常用的Linux命令
查看>>
事件 和 委托
查看>>
C++学习指南
查看>>
asp.net中一般处理程序中添加session
查看>>
转:CentOS 6.5 nginx
查看>>
易之 - 我是个大师(2014年3月6日)
查看>>
【洛谷3932】浮游大陆的68号岛
查看>>
如何看待淘宝二手交易APP“闲鱼”推出的新功能“闲鱼小法庭”?
查看>>