在IO的学习中,BufferReader/Writer这两个类是包装类,里面可以传入一些其他的FileInputStream,于是去学习,什么是装饰者模式。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
具体的就是,我们在实现一个奶茶店的消费系统时,因为有许多小料的加入,如何合理的设计,成为一个麻烦。如果让我们的奶茶单品与每一个小料组合都作为子类,那么类过多,且不方便维护。如果我们在最顶层的类中,加入各个小料的一个Boolean值,用于最后计算Cost。但是这样的话,如果后期有加入,删除,需要修改超类,不安全,且代码进行修改,不能在外修饰。那么装饰者模式应运而生。
什么是装饰者,就是装饰(被装饰),将装饰的属性添加到被装饰的类上,从而使得被装饰的类获得装饰的属性。
下面以一个奶茶的点单系统,来初步的实现,装饰者模式。
超类Drink - 下面有子类单品 MilkTea 和子类小料 MTdecorate
package 设计模式.装饰者模式.练习; /** * @program:多线程和IO * @descripton:超类,价格,描述,cost * @author:ZhengCheng * @create:2021/10/5-16:12 **/ public abstract class Beverage { public abstract float cost(); private float price ; private String context ; public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getContext() { return context; } public void setContext(String context) { this.context = context; } }
MikeTea子类。是所有奶茶单品的父类。
package 设计模式.装饰者模式.练习; /** * @program:多线程和IO * @descripton:奶茶单品的父类 * @author:ZhengCheng * @create:2021/10/5-16:15 **/ public class MilkTea extends Beverage{ @Override public float cost() { return super.getPrice();//奶茶单品只需要返回自己的价格 } }
添加一些单品
package 设计模式.装饰者模式.练习; /** * @program:多线程和IO * @descripton: * @author:ZhengCheng * @create:2021/10/5-16:21 **/ public class MT1 extends MilkTea{ public MT1() { super(); super.setPrice(11.0f); super.setContext("奶茶1号"); } }
public class MT2 extends MilkTea{ public MT2() { super(); super.setPrice(12.0f); super.setContext("奶茶2号"); } }
所有小料的父类,注意小料里面包含了一个Drink ,所以可以修饰Drink
在Override的方法里,与奶茶单品不同,需要加上单品和小料的价格以及描述
package 设计模式.装饰者模式.练习; /** * @program:多线程和IO * @descripton: * @author:ZhengCheng * @create:2021/10/5-16:18 **/ public class Additon extends Beverage{ //需要修饰单品,所以需要包含一个单品 private Beverage mt; public Additon(Beverage mt) { super();//可以不屑,会自己调用父类的。 this.mt = mt; } @Override public float cost() { return super.getPrice()+ mt.cost(); } @Override public void setContext(String context) { super.setContext(mt.getContext()+"-"+context); } }
加入一些小料
public class XL1 extends Additon { public XL1(Beverage mt) { super(mt); super.setContext("小料一号"); super.setPrice(1.0f); } }public class XL2 extends Additon { public XL2(Beverage mt) { super(mt); super.setContext("小料二号"); super.setPrice(2.0f); } }public class XL3 extends Additon { public XL3(Beverage mt) { super(mt); super.setContext("小料三号"); super.setPrice(3.0f); } }public class XL4 extends Additon { public XL4(Beverage mt) { super(mt); super.setContext("小料四号"); super.setPrice(4.0f); } }
最后进行测试
public class TestDemo { public static void main(String[] args) { Beverage mt3 = new MT3(); mt3 = new XL1(mt3); mt3 = new XL2(mt3); mt3 = new XL3(mt3); mt3 = new XL4(mt3); mt3 = new XL4(mt3); System.out.println(mt3.getContext()); System.out.println(mt3.cost()); } }控制台结果:
奶茶3号-小料一号-小料二号-小料三号-小料四号-小料四号
27.0
IO流里的装饰类类似,可以自行体会。