我遇到了Command Design Pattern的困境。 Receiver是知道如何执行操作的类的接口。
在链接中给出的示例案例中,接收者类Stock Trade
知道如何执行2个操作StockTrade#buy
和StockTrade#sell
。这些操作对应于2个现有命令BuyStockOrder
和SellStockOrder
。
但是,如果需要添加其他命令,例如FooStockOrder
和BarStockOrder
会怎样?然后,必须更改Receiver
接口(以及所有现有的实现),因此违反了Open-Closed原则。
如何以Receiver
(几乎)永远不会改变的方式解决这个问题?
答案 0 :(得分:4)
您忘记了S.O.L.I.D原则,特别是Dependancy Inversion
请勿以特别期望具体的方式定义您的界面,例如BuyStockOrder
或SellStockOrder
。
而是定义您的界面以期望像CommandRequest
这样的抽象,然后您将发送CommandRequest
的具体实际情况,而无需更改您的界面。
然后你的Receiver
投诉可以决定如何处理它,当然正确的方法是使用Strategy Pattern,但我会留给你。< / p>
这里有一些代码作为一个简单的例子:
public class Receiver : IReceiver
{
public CommandResult Process(CommandRequest request)
{
// Check the type of request and handle appropriately (or send to who can handle it)
return new Result();
}
}
public interface IReceiver
{
CommandResult Process(CommandRequest request);
}
public abstract class CommandResult
{
public bool Successful { get; set; }
}
public abstract class CommandRequest
{
}
public class Result : CommandResult
{
}
public class BuyStock : CommandRequest
{
public string Name { get; set; }
public decimal Value { get; set; }
}
public class SellStock : CommandRequest
{
public string Name { get; set; }
public decimal Value { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
var receiver = new Receiver();
var result = receiver.Process(new SellStock { Name = "PAYPL", Value = 100.20m });
Console.WriteLine(result.Successful ? "Yay!" : "Boo!");
}
}