zoukankan      html  css  js  c++  java
  • 装饰着模式(Decorator Pattern)

      装饰者模式是动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

      简单的说,装饰者模式由三部分组成,分别是基础抽象类,可以被装饰者包装的类、装饰者类,后两种类均是基础抽象类的子类,但是里面的方法对于基础类有更多的扩展,最终使用,均是使用的基础类进行操作,因此,无论怎么包装,出来的对象都可以使用基础类接收。同时,可以被装饰者包装的类一般使用无参构造,而装饰者类则是使用基础类作为入参的构造函数。

      举个例子,一杯咖啡,他的名字和售价,就可能因为添加不同的调料而导致售价和名称不同,并且调料的组合方式也存在多种。

      在JDK中,I/O就是使用的装饰着模式,如下图所示,InputStrem是装饰者模式的抽象组件,红色标记的4个是可以被装饰者包起来的具体组件,而绿色部分,就是具体的装饰者。

      试用装饰者模式有一个缺点,就是代码中会存在大量的小类,可能会给使用API人造成困扰。

      

       那么,就根据上述举的例子,来写一下装饰者模式

      首先,创建一个抽象类,抽象类中包含一个获取名称的方法和一个获取价格的抽象方法

    package lcl.mm.pattern.decorator;
    
    public abstract class Beverage {
        String desc = "Unknow Beverge";
        public String getDesc(){
            return desc;
        }
    
        public abstract int cost();
    }

      然后,分别创建两个可以被装饰者包装的A咖啡类和B咖啡类,类中一个无参构造函数和一个获取价格的函数,无参构造函数中直接返回咖啡的名称,而价格直接返回自身的价格。

    package lcl.mm.pattern.decorator;
    
    public class CofeeA extends Beverage{
        public CofeeA(){
            desc = "CofeeA";
        }
    
        @Override
        public int cost() {
            return 5;
        }
    }
    package lcl.mm.pattern.decorator;
    
    public class CofeeB extends Beverage{
        public CofeeB(){
            desc = "CofeeB";
        }
    
        @Override
        public int cost() {
            return 10;
        }
    }

    接下来就创建两个装饰者类调味料A和调味料B,类中包含有参构造函数、获取名称方法和获取售价方法,在构造函数中,将Beverage传入,获取名称时,在原有Beverage的名称上加上该调味料的名称,而获取价格的方法是在原有Beverage的售价上加上该调味料的价格、

    package lcl.mm.pattern.decorator;
    
    public class CondimentA extends Beverage {
        Beverage beverage;
        public CondimentA(Beverage beverage){
            this.beverage = beverage;
        }
        public String getDesc(){
            return beverage.getDesc() + ",加调味料CondimentA";
        }
    
        @Override
        public int cost() {
            return 2 + beverage.cost();
        }
    }
    package lcl.mm.pattern.decorator;
    
    public class CondimentB extends Beverage {
        Beverage beverage;
        public CondimentB(Beverage beverage){
            this.beverage = beverage;
        }
        public String getDesc(){
            return beverage.getDesc() + ",加调味料CondimentB";
        }
    
        @Override
        public int cost() {
            return 1 + beverage.cost();
        }
    }

    如上,装饰者模式就写完了,接下来进行测试:

        @Test
        public void decoretorTest(){
            Beverage beverage1 = new CofeeA();
            log.info("Beverage=={}售价:${}",beverage1.getDesc(),beverage1.cost());
            Beverage beverage = new CofeeB();
            log.info("Beverage=={}售价:${}",beverage.getDesc(),beverage.cost());
            beverage = new CondimentA(beverage);
            log.info("Beverage=={}售价:${}",beverage.getDesc(),beverage.cost());
            beverage = new CondimentB(beverage);
            log.info("Beverage=={}售价:${}",beverage.getDesc(),beverage.cost());
            beverage = new CondimentA(beverage);
            log.info("Beverage=={}售价:${}",beverage.getDesc(),beverage.cost());
        }

    输出:

  • 相关阅读:
    图书助手冲刺第四天
    图书助手冲刺第三天
    图书助手冲刺第二天
    图书助手冲刺第一天
    《编写有效用例》读书笔记一
    《需求工程--软件建模与分析》读书笔记三
    《需求工程--软件建模与分析》读书笔记二
    《需求工程--软件建模与分析》读书笔记一
    《探索需求--设计前的质量》阅读笔记三
    “利益相关者”课堂讨论电子版
  • 原文地址:https://www.cnblogs.com/liconglong/p/13227517.html
Copyright © 2011-2022 走看看