七、设计模式——装饰模式
七、设计模式——装饰模式
文森特梵高 发表于3年前
七、设计模式——装饰模式
  • 发表于 3年前
  • 阅读 51
  • 收藏 3
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

咖啡馆订单系统项目

1)咖啡种类:Espresso、ShortBlack、LongBlack、Decaf

2)调料:Milk、Soy、Chocolate

3)扩展性好、方便改动、方便维护

单品的咖啡通过调料混合成卖品。



OO设计方案


定义一个抽象的超类,Drink作为所有咖啡的父类。

咋一看好像能够满足需求,可是仔细推敲,如果加奶的咖啡这种情形怎么表示?或者加奶+巧克力+豆浆的咖啡呢?

这将会是噩梦,因为由此扩展开来的类将会很多很多。


另一个思路,既然每种单品都可以加配料,那么在超类中提供用布尔类型来标记哪些配料需要增加。

分别用三个字段isMilk , isSoy ,isChocolate,子类通过set方法来指定单品需加哪些配料。

这样能够解决类暴炸的问题,我们可以在cost中使用switch来决定结算的价格。

但是这又有扩展性的问题,如果有新调料增加,就必须修改超类。


装饰者模式


装饰者模式像打包快递。

1)有主体 :一个

2)有包装:多层

装饰者模式:动态的将新功能附加到对象上。

装饰层需要持有主体,在自己的方法中加入包装的操作与主体的操作一起完成功能。我自己也晕了...

以下是主体类:

public abstract class Drink {
	public String description="";
	private float price=0f;;
	public void setDescription(String description)
	{
		this.description=description;
	}
	public String getDescription()
	{
		return description+"-"+this.getPrice();
	}
	public float getPrice()
	{
		return price;
	}
	public void setPrice(float price)
	{
		this.price=price;
	}
	public abstract float cost();	
}

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 Decorator extends Drink {
	private Drink Obj;
	public Decorator(Drink Obj){
		this.Obj=Obj;
	};
	@Override
	public float cost() {
		return super.getPrice()+Obj.cost();
	}
	@Override
	public String getDescription()
	{
		return super.description+"-"+super.getPrice()+"&&"+Obj.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);
	}
}

测试代码:

public class CoffeeBar {
	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());
	}
}

运行结果:

order1 price:3.0
order1 desc:Decaf-3.0
****************
order2 price:14.0
order2 desc:Chocolate-3.0&&Chocolate-3.0&&Milk-2.0&&LongBlack-6.0



  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 2
博文 24
码字总数 15386
×
文森特梵高
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: