设计模式的重要性对于程序员来说,相当于盾牌对于美国队长,暴风战斧相对于雷神,内裤对于绿巨人(绿巨人最强武器,手动狗头)来说,是必不可少的。
在此,特别总结下23钟设计模式:
本人将会以专栏形式详细介绍下每种设计模式,文章代码使用java语言,希望能够帮助读者打造一柄编码前行路上的神兵利器。
本文主要针对设计模式的第六种,装饰者模式进行详细介绍
问题:这样设计,会有很多类,当我们增加一个单品咖啡,或者一个新的调料,类的数量就会倍增,就会出现类爆炸
前面分析到方案 一 因为奶茶单品+配料组合会造成类的倍增,因此可以做改进,将配料内置到 MilkTea 类,这样就不会造成类数量过多。从而提高项目的维护性(如图)
说明: redBean,coconut,zhenzhu可以设计为 Boolean,表示是否要添加相应的配料
在如图的 Component 与 ConcreteComponent 之间,如果 ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。
RedBeans包含了GangshiMilkTea
中层的Zhenzhu包含了(GangshiMilkTea+RedBeans)
最外层的Zhenzhu包含了(GangshiMilkTea+RedBeans+Zhenzhu)
/**
* 奶茶
*/
public abstract class MilkTea {
public 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;
}
//计算费用的抽象方法
public abstract float cost();
}
/**
* Coco奶茶
*/
public class Coco extends MilkTea {
@Override
public float cost() {
return super.getPrice();
}
}
/**
* 港式奶茶
*/
public class GangshiMilkTea extends Coco{
public GangshiMilkTea() {
setDes("港式奶茶...........");
setPrice(10.0f);
}
}
/**
* 焦糖奶茶
*/
public class JiaotangMilkTea extends Coco{
public JiaotangMilkTea() {
setDes("焦糖奶茶...........");
setPrice(12.0f);
}
}
/**
* 鲜芋奶茶
*/
public class XianyuMilkTea extends Coco{
public XianyuMilkTea() {
setDes("鲜芋奶茶...........");
setPrice(13.0f);
}
}
/**
* 装饰器
*/
public class Decorator extends MilkTea {
private MilkTea milkTea;
public Decorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
@Override
public float cost() {
return super.getPrice()+milkTea.cost();
}
}
/**
* 配料红豆
*/
public class RedBeans extends Decorator{
public RedBeans(MilkTea milkTea) {
super(milkTea);
setDes("加红豆");
setPrice(2.0f);
}
}
/**
* 配料椰果
*/
public class Coconut extends Decorator{
public Coconut(MilkTea milkTea) {
super(milkTea);
setDes("加椰果");
setPrice(3.0f);
}
}
/**
* 配料珍珠
*/
public class Zhenzhu extends Decorator{
public Zhenzhu(MilkTea milkTea) {
super(milkTea);
setDes("加珍珠");
setPrice(4.0f);
}
}
/**
* 下单
*/
public class OrderClient {
public static void main(String[] args) {
//1.点一杯港式奶茶
MilkTea milkTea = new GangshiMilkTea();
System.out.println("港式奶茶的费用: "+milkTea.cost());
System.out.println("港式奶茶的描述: "+milkTea.getDes());
//加红豆
milkTea = new RedBeans(milkTea);
System.out.println("港式奶茶加红豆的费用: "+milkTea.cost());
System.out.println("港式奶茶加红豆的描述: "+milkTea.getDes());
//加椰果
milkTea = new Coconut(milkTea);
System.out.println("港式奶茶加红豆再加椰果的费用: "+milkTea.cost());
System.out.println("港式奶茶加红豆再加椰果的描述: "+milkTea.getDes());
//加珍珠
milkTea = new Zhenzhu(milkTea);
System.out.println("港式奶茶加红豆再加椰果再加珍珠的费用: "+milkTea.cost());
System.out.println("港式奶茶加红豆再加椰果再加珍珠的描述: "+milkTea.getDes());
//加珍珠
milkTea = new Zhenzhu(milkTea);
System.out.println("港式奶茶加红豆再加椰果再加2份珍珠的费用: "+milkTea.cost());
System.out.println("港式奶茶加红豆再加椰果再加2份珍珠的描述: "+milkTea.getDes());
}
}
Java 的 IO 结构,FilterInputStream 就是一个装饰者
上图引用自JAVA IO流结构图概览