`

锈才学设计模式之 —— 装饰者模式(Decorate Pattern)

阅读更多

锈才学设计模式之  —— 装饰者模式 

 

装饰者模式:在运行时动态的将行为扩展到装饰者对象上,符合"对扩展开放,对修改关闭"原则.

 

说明:

       通俗点说,装饰者模式就是,一个类把另一个类装载进来进行包装,实现更多特性,他们都实现相同的接口.比如:

       形像设计店,有顾客进去,设计师就可以把顾客造型,包装成一个新的形象.

       装修公司,接手一个毛坏房,设计师就可以把房子装饰成一个风格时尚的精品房

 

       在设计一个扩展的功能时,一般都是使用继承,由子类继承父类.比如商品对象:

这种继承关系的设计是对功能提供了扩展,但是设计的弹性不够.

比如:

1. 新增了礼包和赠送商品,在暑假大促销活动中,当用户购买了实物商品配送大礼包,购买虚拟商品赠送虚似商品(如游戏装配),在这种情况,商品需要与礼包和赠送商品组合,就不得不重新修改商品的购买规则代码才能满足需求.如果活动取消,又要修改购买规则代码.

2. 其次就是,实物商品有很多种类:图书商品、电子商品、票务商品、食品商品等,礼包也包括:光碟、消费券等,如果具备好的设计,面对众多的业务规则变化,扩展和维护都将是一个非常烦恼的事。

 

我们需要一种面向接口设计、对象之间松耦合的模式,来解决问题。

这里学习的装饰者模式,就提供了一种更具弹性的扩展形式.扩展的时候不需要修改原有的类,就能将新的业务行为增加到原有的对象中.同是做到“对扩展开放,对修改关闭”的OO设计原则.装饰者模式的结构图:

 

根据装饰者模式,将商品的设计做修改。如下图:

 

 

经过装饰者模式的设计后,我们就解决了上述的问题:

礼包和赠送商品都继承了商品抽象类(装饰者接口,这里也可以是实现接口,因为商品是继承商品基类,所以也就采用抽象类),同时礼包和赠送商品中都包括了一个商品基类的引用(如果是接口,就是接口的引用),达到类型一致,面向接口编程。当开展暑假促销活动时,用户购买了一个实物商品(比如一本书),我们就配送一份礼包(比如:购书券).代码如下:

 

示例代码:
    == 商品基类 ==  

package decorator;
//商品基类
public abstract class Merchandise {
	private String merchandiseId;
	private String merchandiseName;
	private Double price;
	private int stock;
	
	//购买
	public void buy(){
		//具体购买规则
	}
}

 

   == 实物商品(图片)类 == 

package decorator;

public class BookMerchandise extends Merchandise{
	//复写购买
	public void buy(){
		
	}
}

 

    == 装饰抽象类 == 

package decorator;
//装饰抽象类或接口
public abstract class Decorator extends Merchandise{
	//继承上面的方法
	public void buy(){
		
	}
	//可以实现一些其它方法
	public abstract String showDescription();
}

 

  == 礼包类 == 

package decorator;
//礼包或赠送商品
public class Gift extends Decorator{
	Merchandise merchandise;//这里是商品基类,也就是被装饰者的基类,在构造器中赋值
	public Gift(Merchandise merchandise){
		this.merchandise = merchandise;
	}
	@Override
	public String showDescription() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public void buy() {
		// 购买行为,可以包括被装饰者的行为如图书商品的购买
		merchandise.buy();//被装饰者的购买
		//礼品的配送(购买)
	}
	
}

 

   == 测试购买商品类 == 

package decorator;
//测试购买
public class BuyTest {
	public static void main(String[] args){
		//直接购买图书商品,
		Merchandise merchandise = new BookMerchandise();
		merchandise.buy();
		
		//-----------------------------------------------
		
		//购买图书商品配送礼包
		Merchandise merchandise1 = new BookMerchandise();
		//将图书商品(merchandise)装饰到Gift(礼包)商品中
		merchandise1 = new Gift(merchandise1);
		//调用礼包的购买(buy)方法,在方法中购买商品的时候配送礼包,或其它行为
		merchandise.buy();
		
		//当购买商品配送其它礼包,可以新增一个商品,
		//实现装饰者接口(Decorator)再将商品装饰进来就可以了	
		//这样以后增加商品或增加行为只要扩展对象就行,不需要修改原来的类.		
	}
}

 

上面的代码中,做到了非常有弹性的扩展性。增加商品或礼包等,都不会影响原有的类。扩展类的行为,只要实现装饰者接口或抽象类,就可以松耦合的增加类,增加行为。

在JDK AIP中,有很多地方实现装饰者模式。可以查看JDK查看内置的装饰者模式代码:java.io.InputStream,API结构如图:

 

 

 

 这种设计模式在古时候劳动人民的智慧中就有体现,比如大家都看过<葫芦兄弟>这部动画片吧.葫芦兄弟,有红、橙、黄、绿、青、蓝、紫七个大葫芦娃。每个人都有独特的本领,红娃是大力士,橙娃是千里眼和顺风耳,黄娃是硬铁头,绿娃会火功,青娃有水性,蓝娃有隐身术,紫娃有宝葫芦,但是都斗不过蝎子精和蛇精,只有7个葫芦娃团结一起,集7个人的力量于一身时,才能发挥无穷能量,打败蝎子精和蛇精。这其实也是装饰者模式的例子,7个葫芦娃变成一个葫芦娃时,这个葫芦娃就是装饰者,其它葫芦娃是被装饰者,装饰者集中了大力士、千里眼和顺风耳、硬铁头、火功、水性、隐身术、宝葫芦功能强大。所以能胜利。

 

 

 

  • 大小: 28.8 KB
  • 大小: 23.1 KB
  • 大小: 53.7 KB
  • 大小: 37.4 KB
分享到:
评论

相关推荐

    C#设计模式Decorate

    C#设计模式Decorate

    设计模式之装饰者模式1

    // 第10步:执行RedBalls对象的decorate方法总结装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用

    DecoratePattern

    设计模式之装饰模式的简单代码实现(java)

    23种设计模式的java源代码

    里面包含了23中设计模式源代码,其中包括工厂模式(Factory)、单例(Singleton)、观察者模式(Observer)、适配器模式(Adapter)、Template模式、Decorate模式、proxy模式等 这些代码对于初学者看起来稍微复杂一些,我...

    23种java版设计模式源码案例.zip

    装饰器模式(decorate) 外观模式(facecade) 享元模式(flyweight) 代理模式(proxy) 行为型模式(behaviour) 责任链模式(chainrespon) 命令模式(commond) 解释器模式(interpreter) 迭代器模式(iterator) 中介者模式...

    设计模式(七)之装饰模式.zip

    装饰模式精髓主要在装饰类Decorate.cs及子类中的base(执行父类方法)关键字,这二者体现了设计模式的精髓。

    JAVA23种设计模式代码学习.zip

    获取到【文件夹】名称: decorate_pattern 获取到【文件夹】名称: facade_pattern 获取到【文件夹】名称: flyweight_pattern 获取到【文件夹】名称: interperter_pattern 获取到【文件夹】名称: iterator_...

    23种设计模式的java源代码----容易理解的源代码

    里面包含了23中设计模式源代码,其中包括工厂模式(Factory)、单例(Singleton)、观察者模式(Observer)、适配器模式(Adapter)、Template模式、Decorate模式、proxy模式等 这些设计模式源代码更容易理解

    decorate-demo.zip

    装饰者模式

    超市管理系统java源码swing-king-design:23种java设计模式

    装饰器模式(decorate) 外观模式(facecade) 享元模式(flyweight) 代理模式(proxy) 行为型模式(behaviour) 责任链模式(chainrespon) 命令模式(commond) 解释器模式(interpreter) 迭代器模式(iterator) 中介者模式...

    论文研究-融合DECORATE的异构分类器集成算法.pdf

    在基于Stacking框架下异构分类器集成方式分析的基础上, 引入同构分类器集成中改变训练样本以增强成员分类器间差异性的思想, 提出融合DECORATE的异构分类器集成算法SDE, 在1-层泛化利用DECORATE算法, 向1-层训练集...

    Python库 | decorate-0.0.13-py3-none-any.whl

    python库,解压后可用。 资源全名:decorate-0.0.13-py3-none-any.whl

    小书匠语法说明之html属性配置decorate1

    书匠语法说明之书匠语法说明之html属性配置属性配置decorate小书匠小书匠概述概述效果疑问疑问相关相关书匠语法说明之html属性配置decorate相关疑

    es-decorate:CoffeeScript 的 ES7 装饰器

    es-decorate填补了语法空白,提供了一个辅助函数,可以应用符合提议的装饰器 API 的装饰器。 安装 npm install --save es-decorate 用法 遵循的示例: decorate = require ' es-decorate ' # Class decorator ...

    decorate:Clojure宏,用于装饰函数

    这是一个用于Compojure的小型库,该库允许通过装饰器功能来增强定义的功能。 例如,这是一个日志装饰器函数: (defn wrap-logging [func desc] (fn [& args] (prn "Entering" desc) (apply func args) (prn ...

    graphql-decorate:使用灵活的API轻松装饰graphql-ruby类型

    GraphQL装饰graphql-decorate添加了一个易于使用的界面来装饰类型。 它使您可以将逻辑从类型文件中移出并保持声明性。安装将此行添加到您的应用程序的Gemfile中: gem 'graphql-decorate' 然后执行: $ bundle或将其...

    angular-decorate:Javascript 装饰器 + Angular 1.x

    Angular 1.x 的 Javascript 装饰器 使用 ES6 编写 Angular 1.x 应用程序? 厌倦了声明类、添加手动注入以及使用 angular 模块注册所有内容? 不要怕! 适用于 babelJS 和理论上的 Typescript 1.5+(即将推出!) ...

    Decorate Editor Sharp-开源

    装饰编辑器Sharp是一个程序,旨在使用ZDoom的DECORATE块轻松创建自己的怪物和物品。 它是用SharpDevelop用C#编写的。 它需要.NET 2.0框架。

    ng-decorate:[已弃用] AngularJS 1.x的ES7装饰器

    描述Angular 1.x的ES7装饰器。 帮你: 使用ES6模块时,避免Angular的依赖项注入。 使自定义指令声明非常简短且具有语义。 直接在类属性上声明可绑定对象。 非常适合ES7 / TypeScript应用程序。 本自述您已经使用假定...

    react-decorate-props:react-decorate是一个高阶组件,可以帮助您连接className,合并样式并转发其余道具

    React装饰道具 react-decorate-props是一个,可以帮助您连接className ,合并style并转发其余的props。 在render()不再有const {className, style, ...others} = this.props 。 用法 // Instead of... class Foo ...

Global site tag (gtag.js) - Google Analytics