Java设计模式二:装饰者模式——案例分析

现在有一个咖啡馆订单系统项目(要求如下)

咖啡馆订单项目

1)咖啡种类EspressoShortBlackLongBlackDecaf

2)调料MilkSoyChocolate

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

1.如果用我们传统的面向对象思想设计:可以设计出一个这样的,像我一样基础不好的小伙伴看到这种图可能懵逼,不用担心,下面有讲解。

Java设计模式二:装饰者模式——案例分析_第1张图片

咖啡有EspressoShortBlackLongBlackDecaf  这四种单品,配料有MilkSoyChocolate 这三种,现在为了计算一名顾客点餐消费数额。

设计了一个超类,里面有抽象方法cost(),然后让所有单品或者组合的套餐继承这个超类,每个套餐或单品有自己的价格,这样似乎就解决了问题。

这样做的话无论顾客点何种套餐,我们都可以在这个超类的子类种找到对应的套餐,看起来似乎问题得到了解决,实际上隐患很大。

试想一下那么组合的方式到底有多少种?用数学方式计算吗,那辛亏是个小店,不然这种类的数量爆炸的事情不得累死我们,更何况刁钻的顾客想要两份牛奶配料什么的,这又得怎么计算。想想都觉得不如让收银员用计算器自己算吧,

 

2.装饰者模式了解:

1装饰者模式就像打包一个快递

1主体陶瓷衣服

2包装报纸填充塑料泡沫纸板木板

假如我想要一件衣服,先给我用塑料泡沫填充一下,再给我用两份纸板包装起来,然后我为了保险,又用木板再包装起来,假如用之前的设计方法,是不是得再继承出一个子类,单独写一个这样的套餐?细思极恐,这样怕不是会失业

这样的模式应用于之前我们的咖啡馆项目可以这样设计:

Java设计模式二:装饰者模式——案例分析_第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();
	
}

这里有个设计的方法,可能会引起误会,因为现在被装饰者是Coffe类的单品,它的计费方式就是自身的价格, 但是加配料的计费方式就是在原有的基础上再加钱了,这也是为什么在超类里设计cost方法是抽象方法的原因了。

先让Coffe类继承这个超类:

public  class Coffee extends Drink {

	@Override
	public float cost() {
		// TODO Auto-generated method stub
		return super.getPrice();
	}

	
}

再让装饰者也继承这个超类:

public  class Decorator extends Drink {
	private Drink Obj;

	public Decorator(Drink Obj){
		this.Obj=Obj;
	};
	
	
	@Override
	public float cost() {
		// TODO Auto-generated method stub
		
		return super.getPrice()+Obj.cost();
	}

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

 

为一个菜鸟,我可以这样理解,超类是Drink ,以上的设计模式又两个分支,一个是Coffee单品分支,一个是配料decorator分支,假设顾客点一份LongBlack 配上两份牛奶

LongBlack的类是这样的:

 

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

}

牛奶Milk的类是这样的:

public class Milk extends Decorator {

	public Milk(Drink Obj) {		
		super(Obj);
		// TODO Auto-generated constructor stub
		super.setDescription("Milk");
		super.setPrice(2.0f);
	}

}

注意看好,现在点餐代码:

Drink drink = new LongBlack();

//这个drink现在就是我们想要的LongBlack

 

//下面这样赋值类似于传统的 i=i++; 把原有的赋值给新的,这里要是不理解,可以参照上面的源码,一定要搞懂哇。两杯牛奶就写两遍。

drink = new Milk(drink);

drink = new Milk(drink);

//现在输出drink.cost();就是总价格了

代码一定要仔细揣摩,和我一样的菜鸟可能要花半个小时才能明白奥义。

有问题一定留言哦,不要看不懂悄悄划走,我也写了不少博客了,但却没多少人看,很希望有读者提出建议,后面我会一边学习一边把23个常用设计模式整理完毕的。

 

 

 

 

 

 

 

你可能感兴趣的:(设计模式)