设计模式学习-装饰模式
维护系统,需求变更是程序猿心中永远的痛...
(虚拟场景)这不,老大刚过来说,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());
}
{
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());
}
{
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();
}
{
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();
{
MessageManage msg = new MessageManage();
ConcreteDecoratorA actionA = new ConcreteDecoratorA(msg);
Console.WriteLine(actionA.GetMessage());
Console.ReadLine();
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();
}
{
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();
{
MessageManage msg = new MessageManage();
ConcreteDecoratorA actionA = new ConcreteDecoratorA(msg);
ConcreteDecoratorB actionB = new ConcreteDecoratorB(actionA);
Console.WriteLine(actionB.GetMessage());
Console.ReadLine();