在这种情况下,什么设计模式符合要求?

时间:2009-12-06 05:30:33

标签: c# design-patterns

我正在编写一个通过HTTP网关接收SMS消息的应用程序。我将要处理的主要参数是发件人的电话号码和邮件本身。但是,根据消息中的关键字,我需要执行不同的逻辑/返回不同的响应。首先,我使用了一个简单的if / else转换成switch语句,现在我想要清理一下。

我认为需要的是某种命令模式的实现,但我不确定。我可以将每个操作实现为命令对象,并使用命令处理器将它们全部注册,但是我必须实现类似CanExecute(...)函数的操作来确定要执行的相应命令。应该执行命令的条件可能取决于几个因素,例如关键字或特定的消息内容。

我在考虑以下内容:

public interface ISmsCommand 
{
    bool CanExecute(string sender, string message);
    string Execute(string sender, string message);
}

public class SmsHelpCommand : ISmsCommand 
{
    public bool CanExecute(string sender, string message)
    {
        return (message.ToLower().StartsWith("help"));
    }

    public string Execute(string sender, string message) 
    {
        return "For more info, visit...";
    }
}

public class SmsHttpHandler : IHttpHandler
{
    List<ISmsCommand> _commands = new List<ISmsCommand>();

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        var sender = context.Request.Form[...];
        var message = context.Request.Form["Message"];

        foreach (var command in _commands) 
        {
            if (command.CanExecute(sender, message))
            {
                var response = command.Execute(sender, message);
                SendTextMessage(sender, response);
                break;
            }
        }
    }
}
但是,关于这段代码的一些东西对我来说似乎很可疑。我想我不喜欢将参数发送到CanExecute函数和Execute函数,但我不确定。有什么想法吗?

4 个答案:

答案 0 :(得分:1)

在传递给命令之前,应该提前解析消息。至少足以确定哪个命令适用。换句话说,命令对象不应该负责确定消息是否表示该命令。命令的状态方法应仅确定特定命令是否适用于给定状态。您不应该询问每个命令是否需要该消息。

我会有GetBalanceCommand,TransferMoneyCommand等命令。然后有一个简单的字符串标记器解析消息并确定要实例化哪个命令对象并将标记化字符串传递给命令的CanExecute / Execute方法。

答案 1 :(得分:1)

查看责任链模式。 http://www.dofactory.com/patterns/PatternChain.aspx。或者,您可以将Execute方法重命名为TryExecute并返回一个bool。

答案 2 :(得分:1)

答案 3 :(得分:1)

我会继续使用命令模式,但请记住模式只是指导方针(尽管我想这不用说)。

虽然通常在命令模式中为你提供执行命令的东西。想想SqlCommand对象是如何工作的,你给它SqlConnection并告诉它执行。命令对象使用SqlConnection执行所需操作。你把脚放在油门踏板上,它会移动所有连杆,以使车速更快。你不要踩油门,然后自己打开油门。

我建议您在命令的构造函数中为命令提供允许该功能的SendTextMessage函数或对象(想想SqlConnection)。或者只需使用Execute方法以及sendermessage。这使您能够只允许命令执行它的工作。同时允许您通过您提供的SendTextMessage功能限制其执行此操作的能力。如果可以,它会这样做,如果它不能,因为它不应该给出消息,它将不会发送消息。