一、概述通常來說,“行為請求者”與“行為實現者”是緊耦合的。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。在這些情況下,將“行為請求者”與“行為實現者”解耦,實現二者之間的松耦合就至關重要。命令模式是解決這類問題的一個比較好的方法。二、命令模式命 ...
一、概述
通常來說,“行為請求者”與“行為實現者”是緊耦合的。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。在這些情況下,將“行為請求者”與“行為實現者”解耦,實現二者之間的松耦合就至關重要。命令模式是解決這類問題的一個比較好的方法。
二、命令模式
命令模式將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。
命令模式的結構圖如下
Command定義了命令的介面
ConcreteCommand實現Command介面,定義了具體的命令
Client用於創建具體的命令並設定接收者
Invoker要求Command執行相應的請求
Receiver實施與執行一個請求,任何一個類都可能作為Receiver。
三、示例
假定要實現一個繪圖系統,要求支持撤銷功能,下麵就用命令模式來實現這一需求。
首先定義一個抽象的命令介面
public interface IGraphCommand { void Draw(); void Undo(); }
接著實現具體的繪圖命令
public class Line : IGraphCommand { private Point startPoint; private Point endPoint; public Line(Point start, Point end) { startPoint = start; endPoint = end; } public void Draw() { Console.WriteLine("Draw Line:{0} To {1}", startPoint.ToString(), endPoint.ToString()); } public void Undo() { Console.WriteLine("Erase Line:{0} To {1}", startPoint.ToString(), endPoint.ToString()); } } public class Rectangle : IGraphCommand { private Point topLeftPoint; private Point bottomRightPoint; public Rectangle(Point topLeft, Point bottomRight) { topLeftPoint = topLeft; bottomRightPoint = bottomRight; } public void Draw() { Console.WriteLine("Draw Rectangle: Top Left Point {0}, Bottom Right Point {1}", topLeftPoint.ToString(), bottomRightPoint.ToString()); } public void Undo() { Console.WriteLine("Erase Rectangle: Top Left Point {0}, Bottom Right Point {1}", topLeftPoint.ToString(), bottomRightPoint.ToString()); } } public class Circle : IGraphCommand { private Point centerPoint; private int radius; public Circle(Point center, int radius) { centerPoint = center; this.radius = radius; } public void Draw() { Console.WriteLine("Draw Circle: Center Point {0}, Radius {1}", centerPoint.ToString(), radius.ToString()); } publi cvoid Undo() { Console.WriteLine("Erase Circle: Center Point {0}, Radius {1}", centerPoint.ToString(), radius.ToString()); } }
然後再定義繪圖類作為命令接收者
public class Graphics { Stack<IGraphCommand> commands =new Stack<IGraphCommand>(); public void Draw(IGraphCommand command) { command.Draw(); commands.Push(command); } public void Undo() { IGraphCommand command = commands.Pop(); command.Undo(); } }
最後看一下如何調用
static void Main(string[] args) { Line line =new Line(new Point(10, 10), new Point(100, 10)); Rectangle rectangle =new Rectangle(new Point(20, 20), new Point(50, 30)); Circle circle =new Circle(new Point(500, 500), 200); Graphics graphics =new Graphics(); graphics.Draw(line); graphics.Draw(rectangle); graphics.Undo(); graphics.Draw(circle); Console.ReadLine(); }