zoukankan      html  css  js  c++  java
  • 面向对象编程思想-装饰模式

    一、引言

    移动互联时代,手机的使用已经几乎普及到每个人,但是大家有没有想过为什么买的手机通常不会带有贴膜、保护壳?嗯,这个很容易理解,因为这些东西属于装饰手机的配件,买到的手机核心职责和行为已经实现了,至于想怎么装饰手机,有的人想给手机配个钥匙链挂着,有的人想给手机再加一层手机包装起来等等。面对这些特殊的手机装饰行为,如果手机的厂商一 一去全部实现,会造成生产过程极其复杂,增加成本,所以买到的手机通常不会带有这些装饰。还有一个现象,淘宝上买手机时为什么默认显示的价格不是手机附带不同个数、种类配件的价格?显然这样的排列组合太多了,通过继承的预编译计算方式是不适用的(这里不适用主要指的是占用页面空间太多),它是采用选择不同配件时(运行时)才进行计算的方式。其实在软件开发中,也会经常存在一类对象添加不同功能的现象。如果将每个功能都添加到主类中,会增加主类的复杂度,不符合程序设计思想,那我们是不是可以把某些特定情况下执行的特定行为分离出去呢?下面请看我们今天学习的装饰模式是如何很好的解决这个问题的:

    二、装饰模式

    定义:以对客户透明的方式动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

    下面是代码demo:

       //手机抽象类 抽象组件类,对象接口
        public abstract class BasePhone
        {
            public abstract void Print();
        }
       //苹果手机类  具体组件类
        public class ApplePhone:BasePhone
        {
            public override void Print()
            {
                Console.WriteLine("我是苹果手机");
            }
        }
       //装饰抽象类 装饰完全取代抽象组件,从外部扩展抽象组件,抽象组件类不需要知道装饰抽象类存在
        public abstract class BaseDecoratorPhone:BasePhone
        {
            private BasePhone phone;
    
            public BaseDecoratorPhone(BasePhone basePhone)
            {
                this.phone = basePhone;
            }
            public override void Print()
            {
                if (phone != null)
                {
                    phone.Print();
                }
            }
        }
       //手机壳类  具体的装饰者类
        class CaseDecorator : BaseDecoratorPhone
        {
            private BasePhone phone;
            public CaseDecorator(BasePhone phone)
                : base(phone)
            {
                this.phone = phone;
            }
            public override void Print()
            {
                base.Print();
                //添加新行为
                AddCase();
            }
            public void AddCase()
            {
                Console.WriteLine("给手机{0}带上保护壳",phone.GetType().Name);
            }
        }
    //贴膜类  具体装饰者类 
        class StickerDecorator:BaseDecoratorPhone
        {
            private BasePhone phone;
    
            public StickerDecorator(BasePhone phone)
                : base(phone)
            {
                this.phone = phone;
            }
            public override void Print()
            {
                base.Print();
                //添加新的行为
                AddSticker();
    
            }
            public void AddSticker()
            {
                Console.WriteLine("给手机{0}贴膜",phone.GetType().Name);
            }
        }
         static void Main(string[] args)
            {
                //买一个苹果手机
                BasePhone phone = new ApplePhone();
                //买一个手机壳
                BaseDecoratorPhone caseDecorator = new CaseDecorator(phone);
                //给手机添加手机壳
                caseDecorator.Print();
                
                BaseDecoratorPhone stickerDecorator = new StickerDecorator(phone);
                stickerDecorator.Print();
                //同时想给手机添加手机壳 添加贴膜
                BaseDecoratorPhone stickerAndCaseDecorator = new StickerDecorator(caseDecorator);
                stickerAndCaseDecorator.Print();
                Console.Read();
            }

    优点:

    1.装饰者模式将类的核心职责与装饰功能分离,简化原有类,去除相关类中的重复逻辑;

    2.与继承都是扩展对象的功能,但比继承更具有灵活性

    缺点:装饰类之间彼此独立,过度使用会产生很多对象,不宜排错

    使用场景:

    1.需要动态给一个对象附加职责

    2.需要增加一些功能的排列组合产生非常大量的功能

    关于装饰者模式的学习就到此结束了,希望能够帮到你,若有不足,欢迎斧正,感谢您的阅读。

  • 相关阅读:
    内存对齐
    类和对象
    C++ 各种继承方式的类内存布局
    静态变量static
    程序内存布局
    String类
    C++与C的区别
    命名空间
    C
    D
  • 原文地址:https://www.cnblogs.com/jdzhang/p/7060222.html
Copyright © 2011-2022 走看看