传统设计模式(三)装饰者模式

说到这个模式的项目实例 虫子也满头疼的 所谓装饰者模式说白了动态将职责附加到对象上。如果你在项目某个场景中需要功能扩展根据基类衍生出非常多的子类,那么装饰者模式无疑是很好的。不过其实在实际的项目中,往往大家不直接衍生子类,而是通过组合的方式,根据逻辑讲各种扩展叠加来,对外公布的只是一个标签一个壳而已。

所以这个章节,虫子就虚构一个实例了。还拿电商来说、点券赠品系统。

背景:

1.所有点券、优惠券、赠品券、积分继承同一个基类 基类券

2.不用种类的券可以混合搭配

3.积分根据不同的场景可以配置不同的规则

4.升级礼券在上层礼券基础上添加

一般情况下 大家可以就这样设计了

/// <summary>
    /// 基卡
    /// </summary>
    public abstract class BaseCard
    {
        public string decription;
        public abstract double cost();

    }

    /// <summary>
    /// 点卡A
    /// </summary>
    public class cardA : BaseCard
    {
        public cardA()
        {
            decription = "cardA";
        }
        public override double cost()
        {
            return 50.00;
        }
    }

    /// <summary>
    /// 优惠券A
    /// </summary>
    public class couponsA : BaseCard
    {
        public couponsA()
        {
            decription = "couponsA";
        }
        public override double cost()
        {
            return 40.00;
        }
    }

    /// <summary>
    /// 优惠券B
    /// </summary>
    public class couponsB : BaseCard
    {
        public couponsB()
        {
            decription = "couponsB";
        }
        public override double cost()
        {
            return 30.00;
        }
    }

    /// <summary>
    /// 国庆礼券
    /// </summary>
    public class GQCard : BaseCard
    {
        cardA a = new cardA();
        couponsA ca = new couponsA();
        public GQCard()
        {
            decription = "GQCard";
        }
        public override double cost()
        {
            return a.cost() + ca.cost();
        }
    }

    /// <summary>
    /// 国庆升级A等礼券
    /// </summary>
    public class GQACard : BaseCard
    {
        cardA a = new cardA();
        couponsA ca = new couponsA();
        couponsB cb = new couponsB();
        public GQACard()
        {
            decription = "GQACard";
        }
        public override double cost()
        {
            return a.cost() +ca.cost()+ cb.cost();
        }
    }

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/project/

设计模式的原则是类应该对扩展开放对修改关闭,而上述设计在礼券升级种类越来越多的情况下并且现有的礼券已经频繁更新的话 对于庞大的礼券系统肯定是不理想的

那么我们换个思路

/// <summary>
    /// 基卡
    /// </summary>
    public abstract class BaseCard
    {
        public string decription;
        public abstract double cost();

    }

    /// <summary>
    /// 点卡A
    /// </summary>
    public class cardA : baseoupons
    {
        BaseCard basec;
        public cardA(BaseCard basec)
        {
            this.basec = basec;
            decription = "cardA," + basec.decription;
        }
        public override double cost()
        {
            return 50.00 + basec.cost();
        }
    }

    /// <summary>
    /// 优惠券A
    /// </summary>
    public class couponsA : baseoupons
    {
        BaseCard basec;
        public couponsA(BaseCard basec)
        {
            this.basec = basec;
            decription = "couponsA," + basec.decription;
        }
        public override double cost()
        {
            return 40.00 + basec.cost();
        }
    }

    /// <summary>
    /// 优惠券B
    /// </summary>
    public class couponsB : baseoupons
    {
        BaseCard basec;
        public couponsB(BaseCard basec)
        {
            this.basec = basec;
            decription = "couponsB," + basec.decription;
        }
        public override double cost()
        {
            return 30.00 + basec.cost();
        }
    }

    /// <summary>
    /// 基类礼券
    /// </summary>
    public class baseoupons : BaseCard
    {
        BaseCard basec;
        public baseoupons(BaseCard basec)
        {
            this.basec = basec;
            decription = basec.decription;
        }
        public baseoupons()
        {

        }
        public override double cost()
        {
            if (basec != null)
            {
                return basec.cost();
            }
            else
            {
                return 0;
            }
        }

    }

让我们看看装饰者模式的强大

BaseCard a = new baseoupons();
            a = new cardA(a);
            a = new couponsA(a);
            a = new couponsB(a);

            Console.WriteLine("国庆礼券由"+a.decription+"组成");
            Console.WriteLine(a.cost().ToString());

            BaseCard b = new cardA(a);

            Console.WriteLine("国庆升级礼券由" + b.decription + "组成");
            Console.WriteLine(b.cost().ToString());
            Console.ReadLine();

总结:继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式,在我们的设计当中应该允许行为可以被扩展,而无需修改现有的代码。就如上述的例子装饰者模式也可以让我们扩展行为。不过装饰者模式也有缺点,它会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

Author:cnblogs 熬夜的虫子

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索double
public
装饰设计模式、java装饰设计模式、java装饰者设计模式、装饰者设计模式、设计模式 装饰器模式,以便于您获取更多的相关知识。

时间: 2024-10-22 10:16:25

传统设计模式(三)装饰者模式的相关文章

PHP设计模式之装饰者模式代码实例

  这篇文章主要介绍了PHP设计模式之装饰者模式代码实例,装饰者模式就是不修改原类代码和继承的情况下动态扩展类的功能,本文就给出了代码实例,需要的朋友可以参考下 定义: 装饰者模式就是不修改原类代码和继承的情况下动态扩展类的功能.传统的编程模式都是子类继承父类实现方法重载,使用装饰器模式,只需添加一个新的装饰器对象,更加灵活,避免类数量和层次过多. 角色: Component(被装饰对象基类) ConcreteComponent(具体被装饰对象) Decorator(装饰者基类) Contret

C#设计模式(9)——装饰者模式(Decorator Pattern)

原文:C#设计模式(9)--装饰者模式(Decorator Pattern) 一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).AccessoriesPhone(挂件手机类)等,这样就会导致 "子类爆炸"问题,为了解决这个问题,我们可以使用装饰者模式来动态地给一个对象添加额外的职责.下面让我们看看装饰者模式. 二.装饰者模式的详细介绍 2.

深入理解JavaScript系列(29):设计模式之装饰者模式详解

 这篇文章主要介绍了深入理解JavaScript系列(29):设计模式之装饰者模式详解,装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数),需要的朋友可以参考下     介绍 装饰者提供比继承更有弹性的替代方案. 装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数). 装饰者用于通过重载方法的形式添加新功能,该模式可以在被装饰者前面或者后面加上自己的行为以达到特定的目的.

PHP设计模式之装饰者模式_php技巧

介绍 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 思维导图   有这样一个项目,做一个餐厅订餐系统.起初的代码结构是这样的.前面有很多Beverage的继承类,现在遇到的问题是牛奶的价钱上涨了,那么所有相关的类,我们都要进行调整,比如Milk,SugarAndMilk类,这种类还有很多,我们需要逐个去修改类中的方法--开发人员每次都做这种事情,要疯了!所以我们要改变现有的结构.以下的图都是简图,实际的图,可没有这么简单.      设计问题: 1>类

学习JavaScript设计模式之装饰者模式_javascript技巧

有时我们不希望某个类天生就非常庞大,一次性包含许多职责.那么我们就可以使用装饰着模式. 装饰着模式可以动态地给某个对象添加一些额外的职责,从而不影响这个类中派生的其他对象. 装饰着模式将一个对象嵌入另一个对象之中,实际上相当于这个对象被另一个对象包装起来,形成一条包装链. 一.不改动原函数的情况下,给该函数添加些额外的功能 1. 保存原引用 window.onload = function() { console.log(1); }; var _onload = window.onload ||

Head First设计模式之装饰者模式

一.定义 装饰者模式,英文叫Decorator Pattern,在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案.   设计原则: 1. 多用组合,少用继承. 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展. 2. 类应设计的对扩展开放,对修改关

PHP设计模式之装饰器模式

装饰器设计模式适用于下列工作场合: 需求变化是快速和细小的,而且几乎不影响应用程序的其他部分.() 使用装饰器设计模式设计类的目标是: 不必重写任何已有的功能性代码,而是对某个基于对象应用增量变化. 装饰器设计模式采用这样的构建方式: 在主代码流中应该能够直接插入一个或多个更改或"装饰"目标对象的装饰器,同时不影响其他代码流. <?php        class CD {            public $trackList;                        

设计模式:装饰者模式

设计模式系列目录 装饰者模式么,在生活中我们是经常接触的.比如像我们这么快节奏的生活,好多都是早上去买煎饼.一般我们会这么说:"来一个粗粮煎饼,加两个鸡蛋,加一根肠" 或者:"来个山东煎饼,只加土豆丝"等等."煎饼" 就是这个么个有弹性的对象,面饼是不变的,其它的像鸡蛋,肠什么的者在装饰面饼.这个也是我们编程时的一个设计原则 对扩展开放,对修改关闭.(在最后我会给出C# 和C++ 两种代码示例) 装饰者模式和"煎饼"差不多,它

.NET简谈设计模式之(装饰者模式)

装饰者模式其实有点难以理解,特别是对初学者来说可能有点晕,因为它的概念互相冲突,哪里互相冲突我们下面会讲解到. 本人保持一贯的写作风格,重在入门.在本人的这篇文章中会用一个比较恰当的比喻来让我们对问题迎刃而解,例子虽然简单但是重点突出. 在写这篇文章之前我在网上大概搜了一下关于"装饰者模式"的一些文章,但是讲解的效果都不太理想.要么就是找书搬过来的,要么就是对着书的例子从新创造一个.我看了大概三四篇这样子,不行看着头晕.文章的主人很想把问题的关键说清楚,但是很少能在原有代码的基础上画龙

设计模式学习--装饰者模式(Decorator Pattern)

概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有着相同的结构.这样一来,在运行的过程中,就可以将这些对象融合在一起,将相同的属性等成员有机的结合,就像生成另外一种类型一样,而实际上,我们并不需要真的创建这个类型,它是动态生成的.这些装饰者既可以组合,也可以撤销组合,既回复到原来对象状态. 示例介绍: 装饰者模式的关键就是装饰者类型的定义,而其中应