二十三种设计模式之装饰者模式

观察者模式定义:

       区别于继承的用于增强对象功能的动态可扩展的设计模式。

什么时候可以使用观察者模式?

       举个栗子,现在咖啡厅想要对外提供几种饮品,黑咖啡和浓咖啡,另外i还会提供一些调料。这时候他们需要计算出不同组合的饮品和调料的价格是多少。

       面对这种问题,我们可能会用常用的继承思想来进行实现,首先定义一个饮料基类,拥有抽象cost方法来计算总费用,定义调料的设置和获取方法,再定义不同的子类实体继承基类,设置不同的调料。

       这样做的缺点:

      1:一旦出现新的调料,我们就必须修改基类中的调料的种类,新增新的方法

      2:会出现新的饮料比如说茶,而饮料基类中的摩卡和奶泡调料就不适合新的饮料类型

      3:如果调料价格有所改变,就必须改变基类中的调料的价格

    以上的几种做法违背了开闭原则,扩展性不够,而装饰者模式则提供给我们另一种方式去增强类的功能,符合开闭原则,而且拥有较好的扩展性,区别于常用的继承。

    以下是装饰者模式的具体代码示例:

//饮料抽象类
public abstract class Beverage {

	String description = "Unkown Beverage";
	
	public String getDescription(){
		return description;
	}
	
	public abstract double cost();
}

//调料抽象类
public abstract class CondimentDecorator extends Beverage {
	public abstract String getDescription();
}

//浓咖啡
public class Espresso extends Beverage {
	public Espresso(){
		description = "Espresso";
	}
	
	@Override
	public double cost() {
		return 1.99;
	}
}

//摩卡
public class Mocha extends CondimentDecorator {
        Beverage beverage;
    
	public Mocha(Beverage beverage) {
	    this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		return beverage.getDescription()+",Mocha";
	}

	@Override
	public double cost() {
		return 0.20 + beverage.cost();
	}
}

//奶泡
public class Whip extends CondimentDecorator {
        Beverage beverage;
    
	public Whip(Beverage beverage) {
	    this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		return beverage.getDescription()+",Whip";
	}

	@Override
	public double cost() {
		return 0.30 + beverage.cost();
	}
}

//装饰者模式测试类
public class StarbuzzCoffeeTest {
	public static void main(String[] args) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription()+"$"+beverage.cost());
		
		Beverage beverage2 = new HouseBlend();
		beverage2 = new Whip(beverage2);
		beverage2 = new Mocha(beverage2);
		
		System.out.println(beverage2.getDescription()+"$"+beverage2.cost());
	}
}

        首先定义出饮料抽象类基类Beverage,在其中定义描述方法和抽象cost方法,继承饮料抽象基类实现一个浓咖啡子类,定义调料抽象类继承饮料基类,再根据调料抽象类实现两个调料子类,最后在测试类中实例化黑咖啡实例,通过实例化不同的调料子类来获得功能增强后的黑咖啡,最后输出调制出黑咖啡所需的材料和花费。

       如果大家有看过我之前写的代理模式,可能会发现,代理模式和装饰者模式有些类似的地方,它们都动态的增加了类的行为,但是他们的主要目的又是不同的,代理模式为目标类生成了代理类,调用者通过调用代理类来调用达到对目标类控制和隐藏的效果,主要是为了控制目标类,而装饰者模式的主要目的是为了扩展功能。

        如果有哪里说的不对的地方,还请大家指出来。

猜你喜欢

转载自blog.csdn.net/w8827130/article/details/81461419