zoukankan      html  css  js  c++  java
  • JAVA中的设计模式四(装饰模式)

    -------装饰模式

      装饰模式(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.总结:

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

  • 相关阅读:
    Android消息队列模型——Thread,Handler,Looper,Massage Queue
    源代码管理十诫
    他们怎样读书和选书(汇总篇)
    Android消息处理机制
    互联网上的免费服务都是怎么赚钱的
    编程是一种对你的身体健康十分有害的工作
    ERROR/AndroidRuntime(716): java.lang.SecurityException: Binder invocation to an incorrect interface
    什么是 MIME Type?
    TCP/IP:网络因此互联
    Eclipse上GIT插件EGIT使用手册
  • 原文地址:https://www.cnblogs.com/GH0522/p/9122443.html
Copyright © 2011-2022 走看看