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

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

说明:

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

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

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

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

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

比如:

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;}@Overridepublic String showDescription() {// TODO Auto-generated method stubreturn null;}@Overridepublic 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个葫芦娃变成一个葫芦娃时,这个葫芦娃就是装饰者,其它葫芦娃是被装饰者,装饰者集中了大力士、千里眼和顺风耳、硬铁头、火功、水性、隐身术、宝葫芦功能强大。所以能胜利。

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

  1. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  2. python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  3. 锈才学设计模式之 —— 策略模式(Strategy Pattern)

    锈才学设计模式之  -- 策略模式 策略模式:把功能提供者单独封装成类,使它们可以互相替换使用,让功能提供者独立于使用者(调用者). 说明: 在面向对象编程中,我们尽量将功能(类)设计成复用,以符合O ...

  4. javascript设计模式之装饰器模式(结构型模式)

    javascript设计模式之装饰器模式 js的设计模式分为创建型模式,结构型模式和行为模式 结构模式描述了如何组合对象以提供新的功能. 装饰器模式是一种常见的结构型模式,我们可以以一个基础对象为基础 ...

  5. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  6. 前端也要学系列:设计模式之装饰者模式

    什么是装饰者模式 今天我们来讲另外一个非常实用的设计模式:装饰者模式.这个名字听上去有些莫名其妙,不着急,我们先来记住它的一个别名:包装器模式. 我们记着这两个名字来开始今天的文章. 首先还是上< ...

  7. 设计模式 之 装饰者模式

    2019独角兽企业重金招聘Python工程师标准>>> 设计模式 之 装饰者模式 装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对 ...

  8. 【设计模式】装饰者模式 ( 概念 | 适用场景 | 优缺点 | 与继承对比 | 定义流程 | 运行机制 | 案例分析 )

    文章目录 I . 装饰者模式概念 II . 装饰者模式适用场景 III . 装饰者模式优缺点 IV . 装饰者模式与继承对比 V . 装饰者模式相关设计模式 VI . 装饰者模式四个相关类 VII . ...

  9. 设计模式学习----装饰器模式

    这两天本来是自在学习java collection Framework的Fail Fast底层机制,看到核心的部分时,突然意识到设计模式的问题,上大学到现在我还没有真正理解过设计模式的概念,于是用了大 ...

最新文章

  1. 基因名2-MAR等错误名字产生原因
  2. 深度学习核心技术精讲100篇(二十五)-58同城是如何构建智能化流量分发的?
  3. 关于ssh 配置文件的参数说明
  4. python中修饰器_python 中的修饰器
  5. POJ 1988 Cube Stacking
  6. makefile懒人版(单个文件编译)
  7. world办公软件小技巧
  8. mysql数据库安装时的默认端口_数据库默认端口号
  9. JAVA实现Html转Pdf(wkhtmltopdf)
  10. 香农编码译码c语言,实验三香农编码.doc
  11. java 腾讯微博模拟登陆_腾讯微博模拟登录
  12. Spec文件中判断是升级or卸载
  13. 基于springboot电影购票管理系统
  14. 【权威发布】360天眼实验室:Xshell被植入后门代码事件分析报告(完整版)
  15. 计算机视觉中文核心期刊
  16. 西安python培训价格
  17. 达梦2245_达梦创建link访问oracle
  18. iOS马甲包系统性全流程把控
  19. 操作系统概论【一】 - - 操作系统概述
  20. 《死亡诗社》经典台词欣赏(转)

热门文章

  1. 机器学习中的目标函数、损失函数、代价函数的区别
  2. 安装Stanza(处理Stanza无法下载语言模型的错误:ConnectionError)
  3. 高德 linux python,Python高德地图API实用篇
  4. pymssql连接SQLServer
  5. 【精】mysql行转列的7种方法及列转行
  6. 教程篇(5.4) 18. 单点登录 ❀ FortiGate 安全 ❀ Fortinet 网络安全专家 NSE 4
  7. 我的世界java版怎么找史莱姆区块_我的世界手机版史莱姆区块查找的两种方法...
  8. c语言10个选手10个评委,求教C语言题:在歌星大奖赛中,有10个评委为参赛的选手打分,分数为1~100分。...
  9. 最近一百年,全球涌现过哪些最顶尖的、最赚钱的公司?它们的共性是什么?
  10. (转)4个最好的PDF搜索引擎