装饰者模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰者模式相关的知识,希望对你有一定的参考价值。

1.什么是装饰者模式

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

2.设计原则

a.封装变化

b.多用组合,少用继承

c.针对接口编程,不针对实现编程

d.为交互对象之间的松耦合而努力

e.遵循开闭原则

3.代码示例

coffee账单的计算

购买coffee时,coffee的价格会根据配料的不同而具有不同的价格,不同的顾客有不同的口味,自然会要不同调料,从而产生不同的账单,那么我们该如何计算

账单呢?此处使用到装饰者模式,简单来说就是coffee属于被装饰者,调料属于装饰者,调料是动态变化的,根据装饰者模式的定义,调料就是我们要附加到coffee

上的‘责任’。

设计思路:

a.首先装饰者与被装饰者要有共同的超类。所有的被装饰着都应该具有自我描述(即coffee名称)以及自己的价格计算方式。因此我们可以先建立一个coffee的超

类Beverage,它具有一个实例变量description,用于描述该coffee,还有一个cost方法用于计算价格,所有的被装饰着都应该继承该类

b.然后再创立装饰者的超类,该超类中只有一个方法就是getDescription(),由于装饰者与被装饰者要有共同的超类,因此此类也要实现Beverage类

大致思路理清开始编码

类图如下:

技术分享图片

/**
 * 装饰者与被装饰者所共有的超类
 * @author user
 *
 */
public abstract class Beverage {

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


/**
 * 所有装饰者都必须实现该类
 * @author user
 *
 */
public abstract class CondimentDecorator extends Beverage {

	public abstract String getDescription();
}


/**
 * 具体的被装饰者类
 * @author user
 *
 */
public class Espresso extends Beverage {

	public Espresso() {
		description = "Espresso";
	}
	
	@Override
	public double cost() {
		return 0.23;
	}

}


/**
 * 具体的被装饰者类
 * @author user
 *
 */
public class HouseBlend extends Beverage {

	public HouseBlend() {
		description = "HouseBlend";
	}
	
	@Override
	public double cost() {
		return 2.13;
	}

}


/*
 * 装饰者摩卡
 */
public class Moca extends CondimentDecorator {

	Beverage beverage;
	
	public Moca(Beverage beverage) {
		this.beverage = beverage;
	}
	
	@Override
	public String getDescription() {
		return beverage.getDescription() + ",moca";
	}

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

}


/*
 * 装饰者奶泡
 */
public class Milk extends CondimentDecorator {
	
	Beverage beverage;
	
	public Milk(Beverage beverage) {
		this.beverage = beverage;
	}

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

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

}


public class AppTest {

	public static void main(String[] args) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription()+":"+beverage.cost());
		
		Beverage beverage1 = new Espresso();
		beverage1 = new Moca(beverage1);
		System.out.println(beverage1.getDescription() +":"+beverage1.cost());

		Beverage beverage2 = new Espresso();
		beverage2 = new Moca(beverage2);
		beverage2 = new Milk(beverage2);
		System.out.println(beverage2.getDescription() +":"+beverage2.cost());
	}
}


测试结果:

Espresso:0.23
Espresso,moca:0.43000000000000005
Espresso,moca,Milk:0.93

总结:

    技术分享图片

 OO原则:

封装变化

多用组合,少用继承

针对接口编程,不针对实现编程

为交互对象之间的松耦合设计而努力

对扩展开放,对修改关闭(本章节新学习的OO原则)

l  OO模式

装饰者模式—动态地将责任附加到对象上,想要扩展功能,装饰者提供有别于继承的另一种选择。

l  要点归纳

继承和装饰者都可以让我们扩展行为,但继承不是弹性设计的最佳方案。

装饰者模式意味着一群装饰者类,装饰者类反应了被装饰组件的类型,可以用多个装饰者包装对象。

装饰者可以在被装饰者的行为之前或者之后加上自己的行为,甚至将被装饰者的行为取代,以到达特定目的。

装饰者模式会导致设计中出现许多小对象,过度使用会使程序变得复杂。


以上是关于装饰者模式的主要内容,如果未能解决你的问题,请参考以下文章

Java设计模式之装饰者模式

设计模式整理_装饰者模式

设计模式-装饰者模式(Go语言描述)

设计模式-装饰者模式(Go语言描述)

装饰者模式

设计模式 之 装饰者模式