定义
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。特点是开发-闭合原则。
适用场景
- 需要扩展一个类的功能,或给一个类添加附加职责。
- 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
- 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
代码实现
- 新建一个抽象类Beverage,作为所有类的超类。子类必须要实现cost()方法。
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
- CoffeeBeverage继承Beverage 类,并实现cost()方法。同理还有TeaBeverage类,代码这里就不展示。
public class CoffeeBeverage extends Beverage{
public CoffeeBeverage() {
description = "Coffee Beverage";
}
@Override
public double cost() {
return 22.0;
}
}
- CondimentDecorator类同样继承Beverage类,作为调味品的父类。所有的调料装饰者都必须重新实现getDescription()方法这样才能够用递归的方式来得到所选饮料的整体描述。
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
- Milk作为一款调味品继承CondimentDecorator抽象类,实现了cost()和getDescription()方法。Whip和Coconut两个类相同实现。
public class Milk extends CondimentDecorator{
private Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
getDescription();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
@Override
public double cost() {
return 3.0+beverage.cost();
}
}
- 最后是测试类,主要是装饰者的调用方式。
public class Decoratortest{
public static void main(String[] args) {
Beverage beverage = new CoffeeBeverage();
beverage = new Milk(beverage);
beverage = new Whip(beverage);
System.out.println("Coffee cost: "+beverage.cost()+", "+beverage.getDescription());
Beverage beverage2 = new TeaBeverage();
beverage2 = new Milk(beverage2);
beverage2 = new Coconut(beverage2);
System.out.println("Tea cost: "+beverage2.cost()+", "+beverage2.getDescription());
}
}
最终结果。
Coffee cost: 27.0, Coffee Beverage, Milk, Whip
Tea cost: 20.0, Tea Beverage, Milk, Coconut
优点
- 装饰者模式与继承关系的目的都是要扩展对象的功能,但是装饰者可以提供比继承更多的灵活性。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点
- 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
- 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂,造成类的爆炸。
为什么使用抽象类不使用接口?
因为接口必须实现所有方法,而抽象类只需要实现抽象方法,有些方法是可以使用父类的。
网友评论