【大话设计模式系列】之装饰者模式

装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

      利用组合(composition)和委托(delegation)可以在运行时具有继承行为的效果。通过动态的组合对象,可以在新的代码添加新功能,而无须改动现有代码。既然没有改动现有代码,那么引进bug或产生意外的副作用的机会将大幅度减少。

      利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能都利用组合的做法扩展对象的行为,既可以在运行时动态的进行扩展。



开闭原则:类应该对扩展开放,对修改关闭。代码应该如晚霞中的莲花一样的关闭(免于改变),如晨曦中的莲花一样的开放(能够扩展)。在遵循选择需要扩展的代码部分时要小心。每个地方都要采用开闭原则是一种浪费,也没有必要,通常会引入新的抽象层次,增加代码的复杂度,应该把注意力集中在设计中最有可能改变的地方。


【大话设计模式系列】之装饰者模式_第1张图片








   【大话设计模式系列】之装饰者模式_第2张图片


//Beverage是一个抽象类,有两个方法getDescription()和cost()
public abstract class Beverage{
	String description="Unknown Beverage";
	
	//getDescription()已经在此实现了,但是cost必须在子类中实现。
	public String getDescription() {
		return description;
	}	
	public abstract double cost();
}


/*首先,必须让CondimentDecorator能够取代Beverage,所以将CondimentDecorator扩展为Beverage类。
所有的调料装饰者都必须重新实现getDescription()方法 */
public abstract class CondimentDecorator extends Beverage{
	public abstract String getDescription();
}

//写饮料的代码:
//首先,让Espresso(浓缩咖啡)扩展自Beverage类,因为是一种Espresso饮料。
public class Espresso extends Beverage{
	public Espresso(){
		//为了要设置饮料的描述,我们写了一个构造器。
		description="Espresso";
	}
	public double cost(){
		return 1.99;
	}
}


//写调料代码
//Mocha是一个装饰者,扩展自CondimentDecorator,CondimentDecorator扩展自Beverage
public class Mocha extends CondimentDecorator{
	Beverage beverage;
	/*要让Mocha能够引用一个Beverage,做法如下:
	  1、用一个实例变量记录饮料,也就是被装饰者。
	  2、想办法让被装饰着(饮料)被记录到实例变量中。如把饮料当做构造器的参数,再由构造器将此饮料记录在实例变量中。*/
	public Mocha(Beverage beverage){
		this.beverage=beverage;
	}
	//我们希望不只是描述饮料,而是完成的连调料也描述出来。所以,首先利用委托的办法,得到一个叙述,然后在其后面加上附加的叙述。
	public String getDescription(){
		return beverage.getDecription()+",Mocha";
	}
	//要计算带Mocha的饮料的价钱,首先把调用委托类给被装饰对象,以计算价钱,然后再加上Mocha的价钱,得到最后结果。
	public double cost(){
		return .20+beveragr.cost();
	}
}


//供应咖啡
public class StarbuzzCoffee{
	public static void main(String args[]){
		//定一杯Espresso,不需要调料,打印出它的描述与价钱。
		Beverage beverage=new Espresso();
		System.out.printIn(beverage.getDescription()+" $"+beverage.cost());
		//制造出一个DarkRoast对象,用Mocha装饰它,用第二个Mocha装饰它,用Whip装饰它。
		Beverage beverage2=new DarkRoast();
		beverage2=new Mocha(beverage2);
		beverage2=new Mocha(beverage2);
		beverage2=new Whip(beverage2);
		System.out.printIn(beverage2.getDescription()+" $"+beverage2.cost());
		//最后再来一杯调料味豆浆,摩卡,奶泡的HouseBlend咖啡。
		Beverage beverage3=new HouseBlend();
		beverage3=new Mocha(beverage3);
		beverage3=new Mocha(beverage3);
		beverage3=new Whip(beverage3);
		System.out.printIn(beverage3.getDescription()+" $"+beverage3.cost());
	}
}


 


你可能感兴趣的:(【大话设计模式系列】之装饰者模式)