设计模式3-装饰者模式

192 阅读2分钟

1.场景问题解决

咖啡厅组合咖啡本体和配料.

1.1 场景描述

  • 咖啡单品----:Decaf(无咖啡因),Espresso(浓咖啡),LongBlack(深黑咖啡),ShortBlack(浅黑),价格各不同
  • 咖啡调料----:Milk(牛奶),mocha(摩卡),chocolate(巧克力),价格各不同

以上单品为一份,然后调料可以自由组合,最终计算出咖啡的金额

1.2 OO设计

  • 继承-->单品和调料有组合的都生成一个类
  • 单品中判断--->单品中判断是否存在某种调料,然后计算时根据是否存在某种调料来判断.

1.3 需求变动

  • 可以配置多份配料
  • 配料新增或修改

1.4 带来问题

配置多份配料或者配料的新增/修改都会带来修改原类.不符合设计原则----类对扩展开放,对修改关闭

2.用设计模式改进

2.1 分析

讲单品和配料都继承一个总的类,里面有cost方法,层层包装;计算时递归层层解包cost计算,计算最终金额.

2.2 重新设计

03装饰者模式-1类图.png

03装饰者模式-2.png

2.3 源码

  • Drink
public abstract class Drink {
	public String description="";
	private float price=0f;
	public abstract float cost();
    set()..;
    get()..;
}

  • package coffee
  • Coffee,Decaf,ShortBlack
public  class Coffee extends Drink {
	@Override
	public float cost() {
		return super.getPrice();
	}
}

public class Decaf extends Coffee {
	public Decaf(){
		super.setDescription("Decaf");
		super.setPrice(3.0f);
	}
}

public class LongBlack extends Coffee{
	public LongBlack(){
		super.setDescription("LongBlack");
		super.setPrice(6.0f);
	}
}

public class ShortBlack extends Coffee{
	
	public ShortBlack(){
		super.setDescription("ShortBlack");
		super.setPrice(5.0f);
	}

}

  • package Decorator
  • Decorator,Chocolate,Milk
public  class Decorator extends Drink {
	private Drink drink;

	public Decorator(Drink drink){
		this.drink=drink;
	}
	
	@Override
	public float cost() {
		return super.getPrice()+drink.cost();
	}

	@Override
	public String getDescription(){
		return super.description+"-"+super.getPrice()+"&&"+drink.getDescription();
	}
}



public class Chocolate extends Decorator {

	public Chocolate(Drink Obj) {		
		super(Obj);
		super.setDescription("Chocolate");
		super.setPrice(3.0f);
	}
}


public class Milk extends Decorator {

	public Milk(Drink Obj) {		
		super(Obj);
		super.setDescription("Milk");
		super.setPrice(2.0f);
	}

}

  • CoffeeBarTest
ublic class CoffeeBarTest {
	public static void main(String[] args) {
		Drink order;
		order=new Decaf();
		System.out.println("order1 price:"+order.cost());
		System.out.println("order1 desc:"+order.getDescription());
		
		System.out.println("****************");
		order=new LongBlack();
		order=new Milk(order);
		order=new Chocolate(order);
		order=new Chocolate(order);
		System.out.println("order2 price:"+order.cost());
		System.out.println("order2 desc:"+order.getDescription());
	}
}

3.java内置装饰者

3.1 类图

03装饰者模式-3-java.io.png

03装饰者模式-3-java.io.png

3.2 源码

示例可以查看 IO基础整理

4.设计模式总结

4.1 定义

装饰者模式: 动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。

5. 设计模式使用场景及注意

IO对象,

6.参考文章

内容总计于HeadFirst设计模式及相关视频 www.cnblogs.com/pdzbokey/p/…