• 设计模式学习-装饰模式


      维护系统,需求变更是程序猿心中永远的痛...

      (虚拟场景)这不,老大刚过来说,XX,你需要把XX系统的站内短信息系统修改一下,接收人打开后,修改短信息状态为已读。

      我:“好的,没问题,这就改。”

      先看看之前的代码,恩,貌似很简单,直接操作数据库修改状态好了。 

    View Code 
        public class MessageManage 
        {
            public string GetMessage() 
            {
                return "短消息XXXXXXXXXX";
            }
        }

        public class Client 
        {
            static void Main() 
            {
                MessageManage msgManage = new MessageManage();
                Console.WriteLine(msgManage.GetMessage());
            }

      修改后的代码:

    View Code 
        public class MessageManage 
        {
            public string GetMessage() 
            {
                return "短消息XXXXXXXXXX";
            }

            public void ChangeStatus() 
            {
                Console.WriteLine("短消息状态修改");
            }
        }

        public class Client 
        {
            static void Main() 
            {
                MessageManage msgManage = new MessageManage();
                msgManage.ChangeStatus();
                Console.WriteLine(msgManage.GetMessage());
            }

      代码测试完,提交了,老大忽然又跑来说,那啥,我刚忘记了,查看完短消息后要保存操作日志到TXT文档里。 

      我心里说:"这些需求早点怎么不提,应该是设计阶段要解决的,乱码三千字...省略...."。没办法,有需求就要改,拿人钱财,替人消灾。
      作为一个有思想的,想进步的猴子,我觉得我不能一而再,再尔三的违反开闭原则。趁现在短消息系统还比较简单,我决定重构短消息这块的代码。功能需求不断增加,用个什么设计模式好呢?记得有一个动态的给对象增加功能的模式。

    模式概述: 

    Decorator Pattern,又叫装饰模式、装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

    UML类图:


    其中类与对象之间的关系为:

    • Component类
      定义装饰对象与被装饰对象的共同的装饰行为

    • ConcreateComponent类
      被装饰的对象

    • Decorator类
      装饰类的抽象类,包含了Component类的实例(表明将来的具体装饰类都有一个明确的装饰对象)并实现Component类中装饰对象和被装饰对象的共同行为,

    • ConcreteDecorator类 
      具体的装饰类,实现了Decorator类

     现在,我们就按装饰模式重构一下我们的代码:

    View Code 
        public abstract class Component 
        {
            public abstract string GetMessage();
        }

        public class MessageManage : Component 
        {
            public override string GetMessage()
            {
                return "短消息XXXXXXXXXX";
            }
        }

        public abstract class Decorator : Component 
        {
            private Component _com;

            public Decorator(Component com) 
            {
                this._com = com;
            }

            public override string GetMessage()
            {
                return _com.GetMessage();
            }
        }

        public class ConcreteDecoratorA : Decorator 
        {
            public ConcreteDecoratorA(Component com)
                : base(com)
            {
            }

            private void changeStatus() 
            {
                Console.WriteLine("短消息状态修改");
            }

            public override string GetMessage()
            {
                this.changeStatus();
                return base.GetMessage();
            }
    客户端调用:
    View Code 
            static void Main()
            {
                MessageManage msg = new MessageManage();
                ConcreteDecoratorA actionA = new ConcreteDecoratorA(msg);
                Console.WriteLine(actionA.GetMessage());
                Console.ReadLine();
    现在我们增加保存日志到Txt的功能,原代码不需要修改,新增代码如下:
    View Code 
        public class ConcreteDecoratorB : Decorator
        {
            public ConcreteDecoratorB(Component com)
                : base(com)
            {
            }

            private void writeLog()
            {
                Console.WriteLine("保存操作日志到Txt文件");
            }

            public override string GetMessage()
            {
                this.writeLog();
                return base.GetMessage();
            }
    客户端代码变为:
    View Code 
            static void Main()
            {
                MessageManage msg = new MessageManage();
                ConcreteDecoratorA actionA = new ConcreteDecoratorA(msg);
                ConcreteDecoratorB actionB = new ConcreteDecoratorB(actionA);
                Console.WriteLine(actionB.GetMessage());
                Console.ReadLine();
    这样,我们比较好的实现了对修改的关闭,对扩展的开放,以后再增加比如打开短消息,通知原用户的功能等也没有问题了
  • 相关阅读:
    164 Maximum Gap 最大间距
    162 Find Peak Element 寻找峰值
    160 Intersection of Two Linked Lists 相交链表
    155 Min Stack 最小栈
    154 Find Minimum in Rotated Sorted Array II
    153 Find Minimum in Rotated Sorted Array 旋转数组的最小值
    152 Maximum Product Subarray 乘积最大子序列
    151 Reverse Words in a String 翻转字符串里的单词
    bzoj3994: [SDOI2015]约数个数和
    bzoj 4590: [Shoi2015]自动刷题机
  • 原文地址:https://www.cnblogs.com/kdalan/p/2536241.html
Copyright © 2020-2023  润新知