设计模式--装饰者模式

Posted

tags:

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

什么是装饰者模式

  俗话说,“人靠衣装,佛靠金装”,大自然中许多事务都会有一些物体来装饰自己。那么在java的世界中这是如何进行模拟的呢?先举个现实中的例子来说明下这个模式究竟是怎么回事的吧。在生活中我们穿的衣服都是各式各样的,且在不同季节数量也是不一的。我们把一个人、一件衣服都看成一个对象,那么Java怎么实现这两者之间的关系。在人这个对象中有个display方法,这个方法需要打印出名字和穿着的衣服名字,这时候你会怎么办呢?装饰者模式就是用来解决这种类型的问题。

深入理解装饰者模式

  现在根据一个实际需求来更加深入理解这个模式。

  有这么一个咖啡厅,咖啡种类有低咖啡因、深焙、浓缩等,可加调料有牛奶、摩卡、豆浆等。客户来点咖啡时,肯定会先点一杯咖啡,然后根据自己的需要来加其他调料,当然也有可能不加调料。客户点咖啡这个动作就相当于在main函数里new出一个咖啡对象,然后根据这个对象添加一些调料,然后根据这些点的东西进行输出价格。

  这个问题相信你已经清楚了,那么这里我就不慢慢引入这个模式,直接介绍这个模式了。

  调料在这里就相当于一个装饰者,而咖啡则是被装饰者。

  为了便于在咖啡中使用调料的相关方法,先定义一个相关抽象类Coffee,然后这个类中有个String类的属性description,有个getDescription方法,这个方法主要就是返回description这个String,还有一个为实现的方法,就是cost,作用就是返回这个东西的价格。

  但是又为了可以区分这两个类,那么在定义一个接口,这个抽象类是Decorator,这个类继承与Coffee,需要把getDescription这个方法定义成抽象的,也就是所有的调料类都必须重写这个方法,这是因为最后输出这个顾客商品描述时需要把咖啡种类和调料进行输出。调料类中也需要有个Coffee属性,用来表示该调料加在什么咖啡里。

  现在来整理下思路,所有的具体咖啡类都必须继承Coffee这个抽象类,并实现其中的一些方法,而调料都必须实现Decorator这个抽象类且包含一个Coffee类型的属性,且实现其中的方法。

  下面就是示例代码:

以下代码不是一个文件

//Coffee.java
public abstract class Coffee {

    protected String description = "unknow coffee";

    public String getDescription() {
        return description;
    }

    public abstract float cost();
}

//Decorator.java
public abstract class Decorator extends Coffee {

    public abstract String getDescription();
}

//Mocha.java
public class Mocha extends Decorator {
    private Coffee coffee;
    
    public Mocha(Coffee coffee) {
        this.coffee = coffee;
        description = "Mocha";
    }
    @Override
    public String getDescription() {
        return coffee.getDescription()+","+description;
    }

    @Override
    public float cost() {
        return coffee.cost()+0.20f;
    }

}

//Milk.java
public class Milk extends Decorator {

    private Coffee coffee;

    public Milk(Coffee coffee) {
        this.coffee = coffee;
        description = "Milk";
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + "," + description;
    }

    @Override
    public float cost() {
        return coffee.cost() + 0.50f;
    }
}

//DarkRoast.java
public class DarkRoast extends Coffee {

    public DarkRoast() {
        description = "DarkRoast";
    }

    @Override
    public float cost() {
        return 1.2f;
    }

}

//HouseBlend.java
public class HouseBlend extends Coffee {

    public HouseBlend() {
        description = "HouseBlend";
    }

    @Override
    public float cost() {
        return 1.4f;
    }

}

//测试类,test.java
public class Test {

    public static void main(String[] args) {
        Coffee coffee = new DarkRoast();
        coffee = new Mocha(coffee);
        coffee = new Milk(coffee);
        System.out.println(coffee.getDescription());
        System.out.println(coffee.cost());
    }
}

  想必你已经知道了输出结果是什么了,那么赶紧动手验证下自己的猜想吧!

  下一篇博客我们将介绍工厂模式,如果你有什么问题可以留言哦

  

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

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

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

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

设计模式 之 装饰者模式

装饰者模式

设计模式之装饰者模式