zoukankan      html  css  js  c++  java
  • 设计模式学习-装饰模式

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

      (虚拟场景)这不,老大刚过来说,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();
    这样,我们比较好的实现了对修改的关闭,对扩展的开放,以后再增加比如打开短消息,通知原用户的功能等也没有问题了
  • 相关阅读:
    Openstack API 开发 快速入门
    virtualBox虚拟机到vmware虚拟机转换
    使用Blogilo 发布博客到cnblogs
    Openstack Troubleshooting
    hdoj 1051 Wooden Sticks(上升子序列个数问题)
    sdut 2430 pillars (dp)
    hdoj 1058 Humble Numbers(dp)
    uva 10815 Andy's First Dictionary(快排、字符串)
    sdut 2317 Homogeneous squares
    hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
  • 原文地址:https://www.cnblogs.com/kdalan/p/2536241.html
Copyright © 2011-2022 走看看