装饰者模式动态的将责任附加到对象上,若要拓展功能,装饰者提供了比继承更有弹性的替代方案。
换言之,装饰者模式动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。该模式以对客 户端透明的方式扩展对象的功能。
(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2)处理那些可以撤消的职责。
(3)当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的 子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
1.Component(被装饰对象的基类)
定义一个对象接口,可以给这些对象动态地添加职责。
2.ConcreteComponent(具体被装饰对象)
定义一个对象,可以给这个对象添加一些职责。
3.Decorator(装饰者抽象类)
维持一个指向Component实例的引用,并定义一个与Component接口一致的接口。
4.ConcreteDecorator(具体装饰者)
具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。
本来是很想把类图画出来的,奈何UML类图不会画,以后学了再补算了哈哈哈。
以《深入浅出设计模式》中的星巴克案例来举例并实现:
话说星巴克卖饮料(Beverage),饮料分为很多种,比如浓缩咖啡(Espresso),或者豆浆(HouseBlend)等,有些顾客想要对饮料加糖(Sugar),有些想要加牛奶(Milk),有些加摩卡(Mocha),有些甚至要多份的牛奶,那么这个程序要怎么设计呢?
我们按照装饰者模式思考:
Component----->Beverage
ConcreteComponent----->Espresso,HouseBlend等
ConcreteDecorator---->Sugar,Milk,Mocha等
现在缺一个装饰者抽象类:
Decorator---->CondimentDecorator类
我们来建立代码逻辑:
Beverage 被装饰对象的基类
package JAVA装饰者模式;
/**
* Author select you from me
* func 被装饰对象的基类
*/
public abstract class Beverage {
String description="Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
Espresso 具体被装饰对象
package JAVA装饰者模式;
/**
* Author select you from me
* func 具体被装饰对象
*/
public class Espresso extends Beverage{
public Espresso(){
description="Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
HouseBlend 具体被装饰对象
package JAVA装饰者模式;
/**
* Author select you from me
* func 具体被装饰对象
*/
public class HouseBlend extends Beverage{
public HouseBlend(){
description="HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
CondimentDecorator 装饰者抽象类
package JAVA装饰者模式;
/**
* Author select you from me
* func 装饰者抽象类
*/
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
Mocha 具体装饰者
package JAVA装饰者模式;
/**
* Author select you from me
* func 具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。
*/
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();
}
}
Soy 具体装饰者
package JAVA装饰者模式;
/**
* Author select you from me
* func 具体的装饰对象
*/
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",Soy";
}
@Override
public double cost() {
return 0.05+beverage.cost();
}
}
Whip 具体装饰者
package JAVA装饰者模式;
/**
* Author select you from me
* func 具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。
*/
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.25+beverage.cost();
}
}
主类:
package JAVA装饰者模式;
/**
* Created by Administrator on 2019-7-22 0022.
*/
public class StarbuzzCoffe {
public static void main(String[] args){
Beverage beverage = new Espresso();
System.out.println(beverage.description+"----"+beverage.cost());
Beverage beverage1 = new HouseBlend();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription()+"-----"+beverage1.cost());
//这三段代码可能不好理解,如果理解不了,替换成下边的注释代码
//Beverage beverage1 = new HouseBlend();
//Beverage beverage2 = new Mocha(beverage1);
//Beverage beverage3 = new Mocha(beverage2);
//Beverage beverage4 = new Whip(beverage3);
//System.out.println(beverage1.getDescription()+"-----"+beverage4.cost());
}
}
作者:select you from me
链接:https://mp.csdn.net/mdeditor/95767335
来源:CSDN
转载请联系作者获得授权并注明出处。