【问题标题】:Adding new commands with Command Design Pattern使用命令设计模式添加新命令
【发布时间】:2015-02-23 08:22:59
【问题描述】:

我对@9​​87654321@ 进退两难。 Receiver 是一个知道如何执行操作的类的接口。

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

但是,如果需要添加其他命令,例如FooStockOrderBarStockOrder,该怎么办?然后,Receiver 接口必须更改(以及所有现有实现),因此违反了开闭原则。

如何以Receiver(几乎)从未改变的方式解决这个问题?

【问题讨论】:

  • 不完全是,因为在提供的示例中,没有实际的 Receiver 类,它应该负责实际执行与命令对应的操作。

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


【解决方案1】:

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

不要以特定的方式定义你的接口,比如BuyStockOrderSellStockOrder

宁可定义您的接口以期望像CommandRequest 这样的抽象,然后您将发送CommandRequest 的具体实现,而无需更改您的接口。

然后你的Receiver 实现可以决定如何处理它,当然正确的处理方法是使用Strategy Pattern,但我会留给你。

下面是一些代码作为一个简单的例子:

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!");
    }
}

【讨论】: