装饰者模式

Posted noino

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰者模式相关的知识,希望对你有一定的参考价值。

装饰者模式:

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

  关键:  装饰者和被装饰者都继承同一个对象,  装饰者继承并不是为了获得父类地行为, 而是达到类型匹配地目的

  通常装饰者模式采用抽象类

技术图片

java中的装饰类: I/O 

  Component--->InputStream

  ConcreteComponent---->FileInputStream, StringBufferInputStream, ByteArrayInputStream..

  Decorator----> FilterInputStream;

  Concrete--->BufferedInputStream...是不是觉得一下子恍然大悟了, 之前一直用输入流的时候套管道--.--;

 

Example:  想象一下, 一家咖啡店, 咖啡里面可以加各种不同地调料, 你要去计算每一种不同搭配的饮料的价格, 怎么办

  1. 简单的继承想法: 先创建一个抽象的Bevarage(饮料)基类, 把计算价格的方法都定义成抽象的, 所有具体的咖啡都继承这个父类, 然后实现自己的几个计算

   如果这么做,我们来考虑几个问题, 1) 首先调料之间就有非常多的组合, 难道你要每一种组合都去实现它的具体类吗, 2) 就算你毅力惊人实现了所有类, 那么要            价格变了, 打折了, 新添加了一种调料, 难道又要重写吗, 显然继承有点难以为继

  所以我们想, 你的咖啡里加了什么调料, 我们可以动态地把价格加上去多好

下面就是一个简单利用装饰模式, 实现动态地计算咖啡价格地例子:

  1) 一个抽象Beverage基类, 含有一个计算cost的抽象方法;

  

public abstract class Bevarage {

    String description;
    public String getDescription() {
        return description;
    }
    
    abstract double cost();

}

 

  2) 普通coffe类和抽象Condiments类都继承Bevarage类, 同时装饰者中含有一个Bevarage对象---->实现装饰模式的关键;

  

public class Coffe extends Bevarage {

    public Coffe() {
        this.description = "Normal Coffe";
    }
    @Override
    double cost() {
        return 5.1;
    }
}

/*不知道这个beverage放在者还是子类里比较好*/
public abstract class CodimentsDecorator extends Bevarage {
    Bevarage bevarage;
}

public class Milk extends CodimentsDecorator {

    public Milk(Bevarage b) {
        this.bevarage = b;
    }
    public String getDescription() {
        return bevarage.getDescription() + ", Milk";
    }
    
    @Override
    double cost() {
        return 0.5 + bevarage.cost();
    }
}

public class Mocha extends CodimentsDecorator {

    public Mocha(Bevarage b) {
        this.bevarage = b;
    }

    @Override
    public String getDescription() {
        return bevarage.getDescription() + ", Mocha";
    }

    @Override
    double cost() {
        return 1.2 + bevarage.cost();
    }
}

public class Test {
    public static void main(String[] args) {
        /*点一杯基本的咖啡, 然后加进去各种调料*/
        Bevarage b = new Coffe();
        Bevarage milk = new Milk(b);
        Bevarage mocha = new Mocha(milk);

        double cost = mocha.cost();
        System.out.println(mocha.getDescription() + "\\ncost " + cost);
    }
}

输出: Normal Coffe, Milk, Mocha
        cost 6.8

以上是关于装饰者模式的主要内容,如果未能解决你的问题,请参考以下文章

Java设计模式之装饰者模式

设计模式整理_装饰者模式

设计模式-装饰者模式(Go语言描述)

设计模式-装饰者模式(Go语言描述)

装饰者模式

设计模式 之 装饰者模式