假设有一个公司要做产品套餐,即把不同的产品组合在一起,不同的组合对应不同的价格。最终呈现出来的效果是:把产品组合的所有元素呈现出来,并显示该组合的价格。

每个产品都有名称和价格,首先设计一个关于产品的抽象基类。

  1.     public abstract class ProductBase
  2.  
  3.     {
  4.  
  5.         public abstract string GetName();
  6.  
  7.         public abstract double GetPrice();
  8.  
  9.     }

所有的产品都必须继承这个基类,比如家居用品、电器产品等,把这些具体的产品提炼成一个继承ProductBase的子类。

  1.     public class ConcretProuct : ProductBase
  2.  
  3.     {
  4.  
  5.         private string _name;
  6.  
  7.         private double _price;
  8.  
  9.         public ConcretProuct(string name, double price)
  10.  
  11.         {
  12.  
  13.             this._name = name;
  14.  
  15.             this._price = price;
  16.  
  17.         }
  18.  
  19.         public override string GetName()
  20.  
  21.         {
  22.  
  23.             return _name;
  24.  
  25.         }
  26.  
  27.         public override double GetPrice()
  28.  
  29.         {
  30.  
  31.             return _price;
  32.  
  33.         }
  34.  
  35.     }
  36.  

然后考虑产品组合。比如卖平底锅,可能送酱油,也有可能送酱油+老坛酸菜,可能的组合包括:
○ 平底锅
○ 平底锅 + 酱油
○ 平底锅 + 酱油 + 老坛酸菜

在这里,可以把酱油,老坛酸菜看作是装饰器,因为每加一个产品,都是在原有的基础上增加的。比如做"平底锅 + 酱油"这个组合,是在"平底锅"的基础上增加了"酱油"。

现在把酱油、老坛酸菜也设计成继承ProductBase的子类,也就是装饰器类。不过,与ConcretProuct类不同的是,装饰器类需要引用ProductBase,在这里,无论是显示产品组合还是计算产品产品组合价格,都离不开这个引用的ProductBase。

  1.    public class Decorator : ProductBase
  2.  
  3.     {
  4.  
  5.         private ProductBase _product = null;
  6.  
  7.         private string _name;
  8.  
  9.         private double _price;
  10.  
  11.         public Decorator(ProductBase product, string name, double price)
  12.  
  13.         {
  14.  
  15.             this._product = product;
  16.  
  17.             this._name = name;
  18.  
  19.             this._price = price;
  20.  
  21.         }
  22.  
  23.         public override string GetName()
  24.  
  25.         {
  26.  
  27.             return string.Format("{0},{1}", _product.GetName(), _name);
  28.  
  29.         }
  30.  
  31.         public override double GetPrice()
  32.  
  33.         {
  34.  
  35.             return _product.GetPrice() + _price;
  36.  
  37.         }
  38.  
  39.     }
  40.  

以上,显示产品名称的时候,把装饰器类Decorator引用的ProductBase的名称和当前名称组合起来,以逗号分隔;显示产品价格的时候,把引用的ProductBase的价格和当前价格相加。

客户端如下:

  1.     class Program
  2.  
  3.     {
  4.  
  5.         static void Main(string[] args)
  6.  
  7.         {
  8.  
  9.             ConcretProuct livingProduct = new ConcretProuct("平底锅",100);
  10.  
  11.             Console.WriteLine(PrintProductDetails(livingProduct));
  12.  
  13.             Decorator dec1 = new Decorator(livingProduct,"海鲜酱油",10);
  14.  
  15.             Console.WriteLine(PrintProductDetails(dec1));
  16.  
  17.             Decorator dec2 = new Decorator(dec1, "老坛酸菜",12);
  18.  
  19.             Console.WriteLine(PrintProductDetails(dec2));
  20.  
  21.             Console.ReadKey();
  22.  
  23.         }
  24.  
  25.         private static string PrintProductDetails(ProductBase product)
  26.  
  27.         {
  28.  
  29.             return string.Format("产品组合:{0}     价格:{1}", product.GetName(), product.GetPrice());
  30.  
  31.         }
  32.  
  33.     }
  34.  

用最简单的例子理解装饰器模式(Decorator Pattern)的更多相关文章

  1. c#设计模式之装饰器模式(Decorator Pattern)

    引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 pub ...

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

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

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

    发现太过于刻意按照计划来写博客,有点不实际,刚好最近在一个网课上复习AOP的知识,讲到了装饰器模式和代理模式,顺便复习总结一下. 首先了解一下装饰器模式,从名字里面可以看出来,装饰器模式就类似于房子装 ...

  4. 23种设计模式之装饰器模式(Decorator Pattern)

    装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...

  5. 【UE4 设计模式】装饰器模式 Decorator Pattern

    概述 描述 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活.是一种对象结构型模式. 套路 抽象构件(Component) 具体构 ...

  6. php装饰器模式(decorator pattern)

    十一点了. <?php /* The decorator pattern allows behavior to be added to an individual object instance ...

  7. 装饰器模式(Decorator)——深入理解与实战应用

    本文为原创博文,转载请注明出处,侵权必究! 1.初识装饰器模式 装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能.其结构图如下: Component为统一接口,也是装饰类和被装 ...

  8. 设计模式(八)装饰器模式Decorator(结构型)

    设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...

  9. 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)

    <?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...

随机推荐

  1. Java 中判断字符串是否为空

    public class TestString { public static void main(String[] args) { String abc = null; //先判断是否为null再判 ...

  2. Java OOM学习

    转载自原文: 什么是java OOM?如何分析及解决oom问题? 什么是OOM? OOM,全称"Out Of Memory",翻译成中文就是"内存用完了",表现 ...

  3. redis主从,哨兵(windows版)

    一.下载 由于redis官方并不支持windows操作系统,所以官网上是下不到的,需要到gitlab上下载,下载地址如下: https://github.com/MicrosoftArchive/re ...

  4. Spring Boot数据库交互

    在上篇文件的基础上进行开发,简单实现一下增.查操作,删除和修改类似,作为一个demo就暂时不做重复工作了,实现原理类似 IDEA创建Spring Boot项目 项目结构 新建MySQL数据库相关信息 ...

  5. 淘宝IP地址库API地址

    淘宝IP地址库:http://ip.taobao.com/instructions.php   接口说明 1. 请求接口(GET): http://ip.taobao.com/service/getI ...

  6. Codeforces Round #213 (Div. 1) B - Free Market 思维+背包 好题

    B - Free Market 思路:这个题怎么说呢,迷惑性很大,题目里说了交换了两个集合的时候如果有相同元素不能交换,感觉如果没 这句话能很快写出来, 其实当交换的两个集合有重复元素的时候只要交换那 ...

  7. git推送本地仓库到github

    总结一下,方便后人,也方便自己查阅.直接写步骤 一.本地创建一个文件夹,在里面写项目的文件(* .php/*.js.....). git本地操作: 1 .  cd  /path/to/project  ...

  8. C# 中使用 Task 实现提前加载

    介绍一种/两种可以提前做点什么事情的方法. 场景 在UI线程中执行耗时操作,如读取大文件,为了不造成UI卡顿,常采用异步加载的方式,即 async/await . 通常的写法是这样的: private ...

  9. React Native之DeviceEventEmitter发送和接收消息完成事件处理

    今天在Demo这样一个项目的时候,首先遇到的第一个问题就是,每次通过dialog选择[本周.本月.本天]时,伴随着内容重新渲染的时候,tab navigator每次都重新创建和渲染,造成性能浪费和用户 ...

  10. CSU - 2059 Water Problem

    Description ​ 一条'Z'形线可以将平面分为两个区域,那么由N条Z形线所定义的区域的最大个数是多少呢?每条Z形线由两条平行的无限半直线和一条直线段组成 Input 首先输入一个数字T(T& ...