装饰者模式——NWU_LK

简介

装饰者模式又称包装模式,是指不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案.属于结构型设计模式
在这里插入图片描述

案例描述及实现

案例描述

咖啡厅售卖咖啡并且可以添加材料,咖啡包括Decaf和ShortBlack两种,材料包括salt和sugar两种。每种咖啡和材料都有各自的描述和价格。顾客在购买咖啡时可以选择一种咖啡并选择添加一个或多种材料。如果按照排列组合的方式去计算每种可能的情况,那么会使得代码非常复杂。因此需要一种全新的模式去解决以上问题。

实现

通过材料对咖啡进行装饰,以实现代码的简便实现。首先构造咖啡的基类饮品类。

public abstract class Drink {
    private String des;   //饮品描述
    private float price=0.0f;  //饮品价格

    public String getDes() { return des; }
    public void setDes(String des) { this.des = des; }
    public float getPrice() { return price; }
    public void setPrice(float price) { this.price = price; }
    //计算当前这杯drink多少钱
    public abstract float cost();
}

在基类的基础上构造咖啡类

public class Coffee extends Drink {
    @Override
    public float cost() { return getPrice(); }
}

在咖啡类的基础上构造Decaf和ShortBlack两类咖啡

public class Decaf extends Coffee {
    public Decaf(){
        setDes("Decaf");
        setPrice(10f);
    }
}
public class ShortBlack extends Coffee {
    public ShortBlack(){
        setDes("ShortBlack");
        setPrice(5f);
    }
}

要实现材料对咖啡的装饰,需要装饰类的基类也继承咖啡的基类饮品类(因为材料也有价格和描述,此处是为了方便所以直接将饮品的材料和价格继承)。其中必须将饮品组合在里边,方便计算总价格。

public class Decorator extends Drink {
    private Drink drink;
    @Override
    public float cost() {
        return drink.cost()+this.getPrice();
    }
    public Decorator(Drink drink){ this.drink=drink; }
    @Override
    public String getDes() { return super.getDes()+" "+super.getPrice()+" && "+drink.getDes(); }
}

在装饰类基类的基础上分别实现salt类和sugar类

public class Salt extends Decorator {
    public Salt(Drink drink) {
        super(drink);
        setDes("salt");
        setPrice(1);
    }
}
public class Sugar extends Decorator {
    public Sugar(Drink drink) {
        super(drink);
        setDes("糖");
        setPrice(2);
    }
}

模拟咖啡厅售卖咖啡的流程,比如顾客要一杯加了salt和sugar的ShortBlack。那么通过代码实现如下,可以很方便的实现装饰的功能,减少了代码的冗余度。

public static void main(String[] args) {
        Drink order = new ShortBlack();
        System.out.println(order.getDes());
        System.out.println(order.cost());
        System.out.println("===============");
        //加sugar
        order = new Sugar(order);
        System.out.println(order.getDes());
        System.out.println(order.cost());
        System.out.println("===============");
		//加salt
        order = new Salt(order);
        System.out.println(order.getDes());
        System.out.println(order.cost());
    }

JAVA中的装饰者模式实现

Java中的IO使用到了装饰者模式。其中InputStream是抽象类,类似上述案例的Drink。FileInputStream是InputStream的子类,类似于上述案例的Decaf和ShortBlack。FilterInputStream是InputStream的子类,类似于上述案例的Decorator,其中组合了InputStream,即被装饰者。而DataInputSream是FilterInputStream的子类,具体的修饰者,相当于上述的salt和sugar。


版权声明:本文为NWU_LK原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。