美文网首页
设计模式--装饰者模式

设计模式--装饰者模式

作者: jack_520 | 来源:发表于2018-08-09 00:35 被阅读0次

ps:本文主要来源<Head First>

给爱用继承的人一个全新的设计眼界.(可以在不修改底层代码的情况下给你的或者别人的对象赋予新的职责)

假设有个咖啡店,店里卖各种饮料。那么初始都有如下设计

抽象类 Beverage(饮料), Beverage类有个方法 cost(),返回饮料的价格,还有个属性 description,用来描述饮料。

那么所有饮料子类都必须继承Beverage,实现cost()方法.

当你购买饮料时,他们根据你购买的饮料的,通过cost()方法就能知道价格。

这样做在只要几种饮料时不会有什么问题,当要求把现有饮料加摩卡,加奶茶,或者加别的调料时,我们也新建一个类,那么类数量就很多,比如摩卡绿茶,奶茶绿茶,摩卡奶茶绿茶等类,当奶茶价格上涨,我们就必须修改与奶茶相关的饮料的cost(),当新上一种调料时,我们就要加好多新类。

这时有人说可以用实例变量与继承来做,不用设计这么多类。

现在Beverage类的cost()方法不再是抽象方法,我们提供cost()实现,让它计算加入各种调料价格。子类仍然覆盖cost(),但是会调用父类的cost(),计算基本饮料加上调料的价格。

这样做仍有不足,1.当出现新的调料,我们就要加新的方法,并改变父类的cost()方法,2.有些子类不需要父类的调料,比如Tea子类不需要whip(奶泡),也不需要hasWhip().

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

类应该对扩展开放,对修改关闭。(但也不必每个地方都采用这个原则,这样会导致代码复杂难以理解)

装饰者模式特点:

装饰者和被装饰对象有相同超类型,可以用一个或者多个装饰者包装一个对象。

ps:装饰者可以在所委托被装饰者的行为之前或者之后加上自己的行为,以达到特定目的。

下面通过具体代码来解决上面的问题。

//这是饮料抽象类

public abstract class Beverage{

  String description = "unknowm beverage";

public String getDescription(){

 return description;

}

}

//这是调料抽象类,也就是装饰者

public abstract class CondimenDecorator extends Beverage{

    public abstract String getDescription();//都必须重新实现改方法

}

//浓缩咖啡饮料

public class Espresso extends Beverage{

public Espresso(){

    descriptioin = "espresso";

}

public double cost(){

return 1.99;

}

}

//其它饮料类也是类似,就不写了。

//这是调料Mocha,它是一个具体装饰者 ,(注意:Mocha类也是Beverage的子类)

public class Mocha extends ConditionDecorator(){

Beverage beverage;//用一个实例变量来记录饮料,也就是被装饰者

public Mocha(Beverage beverage){

this.beverage = beverage;//想办法让被装饰者被记录到实例变量中,这里是通过把饮料当做构造器的参数,由构造器将此饮料传到实例变量

}

public String getDescription(){

return beverage.getDecription()+",mocha";

}

public double cost(){

return 20+beverage.cost();//这里20元是mocha价格。首先把调用委托给被装饰的对象(不一定只是饮料,可能是调料),以计算价格,再加上mocha价格。

}

}

//测试类

public class StarbuzzCoffee{

public static void main(String args[]){

Beverage beverage = new Espressp();

System.out.println(beverage.getDescription()+"     $"+ beverage.getCost());//打印饮料价格。没加任何调料

beverage = new Mocha(beverage);//用Mocha装饰它,就是加了mocha调料。

System.out.println(beverage.getDescription()+"     $"+ beverage.getCost());//打印饮料价格。加mocha调料

beverage = new Mocha(beverage);//用Mocha装饰它,就是再加一份mocha调料。

System.out.println(beverage.getDescription()+"     $"+ beverage.getCost());//打印饮料价格。两份mocha调料

beverage = new Whip(beverage);//用Whip装饰它,就是再加一份whip调料。

System.out.println(beverage.getDescription()+"     $"+ beverage.getCost());//打印饮料价格。两份mocha调料+whip

Beverage beverage2 = new Whip(new Mocha(new Mocha((new Espressp())));

//者两份饮料时一样的

}

}

jdk java.io相关类就是使用了装饰者模式

装饰者模式缺点就是:产生大量的小类,可能导致使用此api程序员困扰。

相关文章

  • 设计模式

    设计模式 单例模式、装饰者模式、

  • 设计模式笔记汇总

    目录 设计原则 “依赖倒置”原则 未完待续... 设计模式 设计模式——策略模式 设计模式——装饰者模式 设计模式...

  • java IO 的知识总结

    装饰者模式 因为java的IO是基于装饰者模式设计的,所以要了解掌握IO 必须要先清楚什么事装饰者模式(装饰者模式...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • JavaScript 设计模式核⼼原理与应⽤实践 之 结构型设计

    JavaScript 设计模式核⼼原理与应⽤实践 之 结构型设计模式 装饰器模式,又名装饰者模式。它的定义是“在不...

  • 8种设计模式:

    主要介绍 单例设计模式,代理设计模式,观察者设计模式,模板模式(Template), 适配器模式,装饰模式(Dec...

  • 装饰者模式

    JavaScript 设计模式 张容铭第十二章 房子装修--装饰者模式 (102页) 装饰者模式(Decorato...

  • Summary of February 2017

    READING Head First 设计模式:完成50%。内容:观察者模式、装饰者模式、工厂模式、单件模式、命令...

  • 装饰对象:装饰者模式

    装饰对象:装饰者模式   这是《Head First设计模式(中文版)》第三章的读书笔记。   装饰者模式,可以称...

  • 设计模式之装饰器模式

    也称装饰者模式、装饰器模式、Wrapper、Decorator。 装饰模式是一种结构型设计模式,允许你通过将对象放...

网友评论

      本文标题:设计模式--装饰者模式

      本文链接:https://www.haomeiwen.com/subject/roefbftx.html