设计模式三之装饰者模式1

  装饰者模式,真是越来越生活化了,其实设计不就是源于生活高于生活吗?人类,一般总是把生活中观察的东西作为原料才能抽象出东西。装饰者模式,就是用各种装饰者对象来给被装饰者装饰,达到人们的多种多样的需求。不举咖啡的例子,实在没喝过几杯正式的咖啡。考虑炒饭,主要的原材料就是饭,但是变种非常多,近几天我就吃过和有深印象的,扬州炒饭、生牛肉炒饭、五香肉丁炒饭、XO酱海鲜炒饭、黄金炒饭、蛋炒饭等,像什么牛肉、葱花、肉丁、鸡蛋就是装饰者了,厨师用他们炒出(装饰出)各种饭。这种模式的优点是可以订制各种各样的需求,不再面临类爆炸的问题,我们只需要用组合就可以解决问题了。

  怎么实现呢?

  

首先看,这是一个抽象被装饰者类,所谓的饭。
package com.csshu;

/**
 * 抽象的组件类,饮料基类,抽象类,是所有饮料的基础类,这里也可以设计成接口
 * @author shujianhua
 *
 */
public abstract class Beverage {
    String description = "Unknown Beverage";

    // 在子类中必须重写这个类
    public String getDescription(){
        return description;
    }

    // 抽象类,子类必须重写它
    public abstract double cost();

}
可以设计成接口也可以是抽象类。

下面这个是装饰者类的抽象类
package com.csshu;

/**
 * 调料装饰者类,抽象的,简称抽象的装饰者类,由众多调料来继承它,属于装饰者类的抽象类
 * 为什么用继承,因为保持类型一致。
 * @author shujianhua
 *
 */
public abstract class CondimentDecorator extends Beverage{

    // 抽象类,子类必须重写它
    public abstract String getDescription();

}
为什么要继承被装饰者类,为了保持类型一致,以后装饰的时候方便,可以说都是大地之物。

下面这个是具体的被装饰者类
package com.csshu;

/**
 * 这是具体的组件类,属于饮料类的一种,属于最原始的东西,比如一杯原味奶茶
 * @author shujianhua
 *
 */
public class Espresso extends Beverage{

    // 考虑饮料的最原始名字,一杯原味奶茶
    public Espresso(){
        description = "Espresso";  // 这个是继承,所以可以用父类的变量
    }
    @Override
    public double cost() {
        return 1.99;
    }

}

package com.csshu;

/**
 * 这是具体的组件类,属于饮料类的一种,属于最原始的东西,比如一杯原味奶茶
 * @author shujianhua
 *
 */
public class HouseBlend extends Beverage{

    // 考虑饮料的最原始名字,一杯原味奶茶
    public HouseBlend(){
        description = "HouseBlend";  // 这个是继承,所以可以用父类的变量
    }
    @Override
    public double cost() {
        return 0.99;
    }

}

下面是具体的被装饰者类,
package com.csshu;

/**
 * 调料装饰者类,具体的,具体的装饰者类
 * @author shujianhua
 *
 */
public class Mocha extends CondimentDecorator{
    Beverage beverage;

    // 通过构造函数来实现包裹类,来装饰
    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }

    // 这个叫做委托
    @Override
    public double cost() {
        return 0.20+beverage.cost();
    }

    // 这个叫做委托delegation,在最后的输出类中可以吧描述,装饰者全部输出
    @Override
    public String getDescription() {
        return beverage.getDescription()+",Mocha";
    }

}

package com.csshu;

/**
 * 调料装饰者类,具体的,具体的装饰者类
 * @author shujianhua
 *
 */
public class Soy extends CondimentDecorator{
    Beverage beverage;

    // 通过构造函数来实现包裹类,来装饰
    public Soy(Beverage beverage){
        this.beverage = beverage;
    }

    // 这个叫做委托
    @Override
    public double cost() {
        return 0.39+beverage.cost();
    }

    // 这个叫做委托delegation,在最后的输出类中可以吧描述,装饰者全部输出
    @Override
    public String getDescription() {
        return beverage.getDescription()+",Soy";
    }

}

package com.csshu;

/**
 * 调料装饰者类,具体的,具体的装饰者类
 * @author shujianhua
 *
 */
public class Whip extends CondimentDecorator{
    Beverage beverage;

    // 通过构造函数来实现包裹类,来装饰
    public Whip(Beverage beverage){
        this.beverage = beverage;
    }

    // 这个叫做委托
    @Override
    public double cost() {
        return 0.53+beverage.cost();
    }

    // 这个叫做委托delegation,在最后的输出类中可以吧描述,装饰者全部输出
    @Override
    public String getDescription() {
        return beverage.getDescription()+",Whip";
    }

}

发现上面并没有上面多大的不同。。

接下来是入口main函数,
package com.csshu;

/**
 * 这里是允许装饰者模式的入口。
 * 我们来看,Beverage是抽象的组件类,HouseBlend和Espresso是具体的组件类
 * CondimentDecorator是抽象的装饰者类,Mocha和Soy以及Whip是具体的装饰者类
 * @author shujianhua
 *
 */
public class DecoratorEnter {

    public static void main(String[] args) {

        Beverage beverage1 = new Espresso();
        System.out.println(beverage1.cost()+"dao,"+beverage1.getDescription());

        Beverage beverage = new HouseBlend();
        beverage = new Mocha(beverage);  // 这里就是包装者,包进去了,其实装饰者装饰的顺序不重要
        beverage = new Soy(beverage);
        beverage = new Whip(beverage);
        System.out.println(beverage.cost()+"dao,"+beverage.getDescription());

    }

}

可以看到,首先new出了一个实体类,然后实体类的引用继续迭代引用其它装饰者包裹的新类。虽然是不断地引用其它,但是实体类的引用在这里面获得了很多新的属性。关键就是委托
(delegation)和接口的使用,一层层的传进去,最后一层层地传出来。
时间: 2024-10-12 20:57:23

设计模式三之装饰者模式1的相关文章

设计模式(三)_装饰器模式

上篇学习了策略模式,现在回想下,什么是策略模式,好了.本篇主要介绍装饰器模式,just do it! 什么是装饰器模式 装饰器模式指的是动态的将责任附加到对象上.若要扩展功能,装饰器模式提供了比继承更弹性的替代方案. 如何使用装饰器模式 老王来到商场买衣服,需要买衣服,裤子,帽子...... public class Wang { public void show(){ System.out.println("我穿上衣服,累计花费100元"); System.out.println(&

Java设计模式(三)-装饰者模式

我们都知道,可以使用两种方式给一个类或者对象添加行为. 一是使用继承.继承是给一个类添加行为的比较有效的途径.通过使用继承,可以使得子类在拥有自身方法的同时,还可以拥有父类的方法.但是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制增加行为的方式和时机. 二是使用关联.组合即将一个对象嵌入到另一个对象中,由另一个对象来决定是否引用该对象来扩展自己的行为.这是一种动态的方式,我们可以在应用程序中动态的控制. 与继承相比,关联关系的优势就在于不会破坏类的封装性,且具有较好的松耦合

head first (三):装饰者模式

看到别人写的,都看不进去,算了还是自己手写一遍吧,算是帮助自己理解了.写的比较简单,例子也比较好懂,什么时候使用自己看着办. 1.定义 装饰者模式:动态地将职责附加到对象上.若要扩展功能,装饰者提供比继承更有弹性的替代方案. 装饰者和被装饰者对象都哟相同的超类. 装饰者会使程序中出现很多小类,增加使用难度 可以透明的插入装饰者,客户都不知道是和装饰者打交道 2:使用场景 对象由主体+许多可选的部件或者功能构成,使用继承或者接口会产生很多类,且很难扩展. 例如,现在需要一杯饮料,主体是水,可以选择

Php设计模式(三):行为型模式part1

原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=5 可以在线运行查看效果哦! 在上一篇我们讲了结构型模式,结构型模式是讨论类和对象的结构的.总共有7种.而今天我们来介绍一下行为型模式. 一.什么是行为型模式? 行为型模式: 就是描述类和对象之间的通信和职责的.简而言之,就是类和对象扮演什么角色,还有怎么扮演这个角色的问题. 二.行为型模式的种类 大体上分为三个大类:常见模式.已知模式.深度模式 常见模式包括: 模版方法模式.命令模式.迭代器模式.观

Php设计模式(三):行为型模式part2

原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=5 可以在线运行查看效果哦! <接上文> 5.中介者模式(Mediator) : 用中介对象封装一系列的对象交互,中介使各对象不需要显式地相互引用.类似于邮局,邮寄者和收件者不用自己跑很远路,通过邮局就可以. 好处:简化了对象之间的关系,减少子类的生成. 弊端:中介对象可能变得非常复杂,系统难以维护. 应用场景:不需要显示地建立交互. 代码实现: ? 1 2 3 4 5 6 7 8 9 10

设计模式C++实现——装饰者模式

模式定义: 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 装饰者和被装饰者有相同的超累类型. 可以用一个或多个装饰者包装一个对象. 既然装饰者和被装饰者对象有相同的超累类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它. 装饰者可以委托被装饰者的行为之前与或之后,加上自己的行为,以达到特定的目的. 对象可以在任何时候被装饰,所以可以在运行时动态地.不限量地用你喜欢的装饰者来装饰对象. 模式结构: 举例: 购买咖啡时,可以在其中加入

设计模式(三)—— 装饰者模式

装饰者模式:动态地将责任附加到对象上.若要拓展功能,装饰者提供了比继承更有弹性的替代方案. 一般装饰者包括组件和装饰者对象,组件基类包含所需要装饰的部分,具体组件和装饰类都继承与组件基类.这样做的保证是能让装饰者与组件是同一个类型. 装饰类一般有组件的引用对象,通过引用对象完成装饰功能,并且可以拓展新的功能.像Java中的I/O. 装饰模式比继承要灵活.避免了继承体系臃肿.而且降低了类于类之间的关系.(继承体系的时候,缓冲类,必须继承相应的类.) 装饰类因为增强已有对象,具备的功能和已有的是相同

设计模式(三)装饰者模式Decorator

装饰者模式针对的问题是:对一个结构已经确定的类,在不改变该类的结构的情况下,动态增加一些功能. 一般来说,都是对一些已经写好的架构增加自己的功能,或者应对多种情况,增加功能. 我们还是来玩一句红警,首先我们进入游戏,这时我们只有一个基地车,右边的界面有个黑色的框,什么操作也没有. 这里,我们假定有个操作的接口Operation public interface Operation { //操作 public void doOperation(); } 我们自己,叫做一个MyOperation,实

设计模式(三)——装饰器模式(Decorator Pattern)

发现太过于刻意按照计划来写博客,有点不实际,刚好最近在一个网课上复习AOP的知识,讲到了装饰器模式和代理模式,顺便复习总结一下. 首先了解一下装饰器模式,从名字里面可以看出来,装饰器模式就类似于房子装潢吧,比如刚买的毛坯房,只有一个没有门,直接就可以进去. 首先设计一个房子类Room,实现一个进入方法Access /// <summary> /// 抽象接口 用来进行约束 /// </summary> public interface IAccess { void Access()