使用Command Design Pattern添加新命令

时间:2015-02-23 08:22:59

标签: oop design-patterns command-pattern open-closed-principle

我遇到了Command Design Pattern的困境。 Receiver是知道如何执行操作的类的接口。

在链接中给出的示例案例中,接收者类Stock Trade知道如何执行2个操作StockTrade#buyStockTrade#sell。这些操作对应于2个现有命令BuyStockOrderSellStockOrder

但是,如果需要添加其他命令,例如FooStockOrderBarStockOrder会怎样?然后,必须更改Receiver接口(以及所有现有的实现),因此违反了Open-Closed原则。

如何以Receiver(几乎)永远不会改变的方式解决这个问题?

1 个答案:

答案 0 :(得分:4)

您忘记了S.O.L.I.D原则,特别是Dependancy Inversion

请勿以特别期望具体的方式定义您的界面,例如BuyStockOrderSellStockOrder

而是定义您的界面以期望像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!");
    }
}