命令模式,作用就是让行为和对象分离,这样可以方便地为对象扩展行为。
对文档的操作:
文档代码:
public class Document { public string Title { get; set; } public string Content { get; set; } //public void Read() //{ // Console.WriteLine("Read "); //} //public void Write() //{ // Console.WriteLine("Write "); //} }
文档对象有两个行为,读和写。如果我要对文档的行为进行扩展,就必须要修改文档,这样违背了开闭原则。
我们把文档的对象和行为进行分离。
public abstract class BaseReceiver { public abstract void Execute(Document doc); } public class ReadReceiver : BaseReceiver { public override void Execute(Document doc) { Console.WriteLine("Read:{0},{1}", doc.Title, doc.Content); } } public class WriteReceiver : BaseReceiver { public override void Execute(Document doc) { Console.WriteLine("Write:{0},{1}", doc.Title, doc.Content); } }
把读取和写入分别建做成不同的对象,进行单一职责的分离。
并且抽象出来,这样就支持灵活的扩展和修改,可以随意增加而不会影响其它任何原有的行为。
包装一层:
public abstract class BaseCommand { public abstract void Execute(Document doc); } public class ReadCommand : BaseCommand { private BaseReceiver BaseReceiver = null; public ReadCommand(BaseReceiver baseReceiver) { BaseReceiver = baseReceiver; } public override void Execute(Document doc) { BaseReceiver.Execute(doc); } } public class WriteCommand : BaseCommand { private BaseReceiver BaseReceiver = null; public WriteCommand(BaseReceiver baseReceiver) { BaseReceiver = baseReceiver; } public override void Execute(Document doc) { BaseReceiver.Execute(doc); } }
这里面的作为,我也搞不懂。待续。
增加一个调用者:
public class Invoker { private BaseCommand baseCommand = null; public Invoker(BaseCommand basecommand) { baseCommand = basecommand; } public void Execute(Document doc) { baseCommand.Execute(doc); } }
同样,待续。
使用:
Document doc = new Document() { Title = "如梦令", Content = "昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道“海棠依旧”。“知否?知否?应是绿肥红瘦。”" }; Console.WriteLine("---行为和对象分离 Receiver---------------------------------"); BaseReceiver write = new WriteReceiver(); write.Execute(doc); BaseReceiver Read = new ReadReceiver(); Read.Execute(doc); Console.WriteLine("---再包装一层 Command---------------------------------"); BaseCommand writeCommand = new WriteCommand(write); writeCommand.Execute(doc); BaseCommand readCommand = new ReadCommand(Read); readCommand.Execute(doc); Console.WriteLine("---再包装一层 Invoker---------------------------------"); Invoker writeinvoker = new Invoker(writeCommand); writeinvoker.Execute(doc); Invoker readinvoker = new Invoker(readCommand); readinvoker.Execute(doc); Console.ReadLine();
运行结果: