zoukankan      html  css  js  c++  java
  • Java学习笔记——设计模式之三.装饰模式

    函数应该做一件事,做好这件事,只做这一件事。

                        ——Clean Code

     

    装饰模式,上代码:

    先定义零件类:

    1 package cn.no3.decorator.template;
    2 
    3 public abstract class Component {
    4 
    5     public abstract void operation();
    6 }

    再定义具体零件类(即被装饰类)继承零件类:

     1 package cn.no3.decorator.template;
     2 
     3 public class ConcreteComponent extends Component{
     4 
     5     @Override
     6     public void operation() {
     7         // TODO Auto-generated method stub
     8         System.out.println("对一个Object进行装饰:");
     9     }
    10 
    11 }

    然后定义装饰类,继承零件类:

     1 package cn.no3.decorator.template;
     2 
     3 public class Decorator extends Component {
     4 
     5     protected Component component;
     6     
     7     public void setComponent(Component component) {
     8         this.component = component;
     9     }
    10 
    11     @Override
    12     public void operation() {
    13         //调用的是传入component的operation方法
    14         if (component != null) {
    15             component.operation();
    16         }
    17 
    18     }
    19 
    20 }

    定义装饰类的子类:

     1 package cn.no3.decorator.template;
     2 
     3 public class ConcreteDecoratorA extends Decorator {
     4 
     5     private String addedField;
     6     
     7     @Override
     8     public void operation() {
     9         // TODO Auto-generated method stub
    10         super.operation();//第一行调用super,则从前往后包装.反之则从后往前包装
    11         addedField = "新的装饰物A";
    12         System.out.println("装饰了:"+addedField);
    13     }
    14 }
    15 
    16 public class ConcreteDecoratorB extends Decorator {
    17     
    18     @Override
    19     public void operation() {
    20         // TODO Auto-generated method stub
    21         super.operation();
    22         AddedBehavior();
    23     }
    24 
    25     private void AddedBehavior() {
    26         // TODO Auto-generated method stub
    27         System.out.println("完成装饰,最后照个相");
    28     }
    29     
    30 }

    测试类测试:

     1 package cn.no3.decorator.template;
     2 
     3 public class _Test {
     4 
     5     public static void main(String[] args) {
     6         //新建装饰对象
     7         ConcreteComponent concreteComponent = new ConcreteComponent();
     8         ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
     9         ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
    10         //逐层包装
    11         //如果注掉下句,还是先调用A的super,发现没传component,于是A的super什么都不做
    12         concreteDecoratorA.setComponent(concreteComponent);//A先调用cC,cC方法不再调用super.
    13         concreteDecoratorB.setComponent(concreteDecoratorA);//B先调用A
    14         //输出最终结果
    15         concreteDecoratorB.operation();
    16     }
    17 }

    把这个例子中的Component类换成接口也是一样的:

    举个例子:

    需求:

    定义一个角色,让他实现IWearable接口,

    再定义装备实现IWearable接口

    人物装备装备.

    上代码:

    1 package cn.no3.decorator.instance;
    2 
    3 public abstract interface IWearable {
    4 
    5     public abstract void operation();
    6 }
     1 package cn.no3.decorator.instance;
     2 
     3 public class Clothes implements IWearable {
     4 
     5     protected IWearable component;
     6     
     7     public void setComponent(IWearable component) {
     8         this.component = component;
     9     }
    10 
    11     @Override
    12     public void operation() {
    13         if (component != null) {
    14             component.operation();
    15         }
    16 
    17     }
    18 
    19 }
     1 package cn.no3.decorator.instance;
     2 
     3 //即使只有一双鞋也要定义父类,否则无法通过对象的super.operation对装饰进行传递
     4 public class Shoes implements IWearable {
     5 
     6     protected IWearable component;
     7     
     8     public void setComponent(IWearable component) {
     9         this.component = component;
    10     }
    11 
    12     @Override
    13     public void operation() {
    14         if (component != null) {
    15             component.operation();
    16         }
    17     }
    18 
    19 }
     1 package cn.no3.decorator.instance;
     2 
     3 public class Weapons implements IWearable {
     4 
     5     protected IWearable component;
     6     
     7     public void setComponent(IWearable component) {
     8         this.component = component;
     9     }
    10 
    11     @Override
    12     public void operation() {
    13         if (component != null) {
    14             component.operation();
    15         }
    16 
    17     }
    18 
    19 }

    他们的子类都是重写父类operation()方法,最先调用(或者最后调用),super.operation();此处省略若干行

     1 package cn.no3.decorator.instance;
     2 
     3 public class WeaponA extends Weapons {
     4 
     5     @Override
     6     public void operation() {
     7         // TODO Auto-generated method stub
     8         super.operation();
     9         System.out.println("装备了:霜之哀伤");
    10     }
    11 }

    角色类

     1 package cn.no3.decorator.instance;
     2 
     3 public class Character implements IWearable{
     4 
     5     @Override
     6     public void operation() {
     7         // TODO Auto-generated method stub
     8         System.out.println("对一个人物进行装备:");
     9     }
    10 
    11 }

    测试类:

     1 package cn.no3.decorator.instance;
     2 
     3 public class _Test {
     4 
     5     public static void main(String[] args) {
     6         //新建装备对象
     7         Character concreteComponent = new Character();
     8         ClotheA fantasyKiller = new ClotheA();
     9         ClotheB bravingArmor = new ClotheB();
    10         WeaponA frostmourne = new WeaponA();
    11         WeaponB DoubleRoses = new WeaponB();
    12         ShoesA shoes = new ShoesA();
    13         //逐层包装
    14         fantasyKiller.setComponent(concreteComponent);
    15         bravingArmor.setComponent(fantasyKiller);
    16         frostmourne.setComponent(bravingArmor);
    17         DoubleRoses.setComponent(frostmourne);
    18         shoes.setComponent(DoubleRoses);//shoes.setComponent(shoes)会陷入死循环
    19         //输出最终结果
    20         shoes.operation();
    21     }
    22 }

    装饰模式是为已有功能动态地添加更多功能的一种方式

    装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

    装饰功能的核心是:把类中的装饰功能从类中搬出去。

  • 相关阅读:
    2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest C
    Codeforces Round #445 div.2 D. Restoration of string 乱搞
    hdu 6228 Tree
    数塔(入门级dp)
    逆序数(归并排序和树状数组)
    poj2104 K-th Number 主席树入门;
    Codeforces Round #466 (Div. 2)F. Machine Learning 离散化+带修改的莫队
    Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow+差分标记
    2038: [2009国家集训队]小Z的袜子(hose)+莫队入门
    Codeforces Round #220 (Div. 2)D. Inna and Sequence 树状数组+二分
  • 原文地址:https://www.cnblogs.com/tomasman/p/6849050.html
Copyright © 2011-2022 走看看