Какой шаблон дизайна отвечает всем требованиям в этом сценарии? - PullRequest
0 голосов
/ 06 декабря 2009

Я пишу приложение для получения SMS-сообщений через HTTP-шлюз. Основные параметры, которые я буду обрабатывать, это номер телефона отправителя и само сообщение. Однако, в зависимости от ключевого слова в сообщении, мне нужно будет выполнить другую логику / вернуть другой ответ. Для начала я использовал простой 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 ]

1 голос
/ 06 декабря 2009

Я бы продолжил с шаблоном команд, но помните, что шаблоны - это просто рекомендации (хотя я думаю, что это само собой разумеется).

Хотя обычно в шаблоне команд вы предоставляете ему что-то для выполнения его команды. Подумайте о том, как работает объект SqlCommand, вы дадите ему SqlConnection и просто скажете ему выполнить. Командный объект использует SqlConnection, чтобы сделать то, что нужно. Вы ставите ногу на педаль газа, и она перемещает все рычаги, чтобы заставить автомобиль двигаться быстрее. Вы не нажимаете педаль газа, а затем открываете газ самостоятельно.

Я хотел бы предложить, чтобы вы либо дали команде функцию или объект SendTextMessage, которая учитывает эту функциональность (представьте SqlConnection) в ее конструкторе. Или просто дайте его с помощью метода Execute вместе с sender и message. Это дает вам возможность просто позволить команде выполнять свою работу. В то же время, позволяя вам ограничить его способность делать это с помощью функции SendTextMessage, вы предоставляете ее. Он сделает это, если сможет, и если не может, поскольку не должен передавать сообщение, он не отправит сообщение.

1 голос
/ 06 декабря 2009

Взгляните на схему цепочки ответственности. http://www.dofactory.com/patterns/PatternChain.aspx. Или вы можете переименовать ваш метод Execute в TryExecute и вернуть bool.

1 голос
/ 06 декабря 2009

Взгляните на команду Factory method и шаблон команды .

1 голос
/ 06 декабря 2009

Синтаксический анализ сообщения должен быть выполнен заранее перед передачей в команду. По крайней мере, достаточно, чтобы определить, какая команда применима. Другими словами, объект команды не должен отвечать за определение того, представляет ли сообщение эту команду. Метод состояния команды должен только определять, применима ли конкретная команда в данном состоянии. Вам не нужно спрашивать каждую команду, хочет ли она получить сообщение.

Я хотел бы иметь такие команды, как GetBalanceCommand, TransferMoneyCommand и т. Д. Затем простой токенайзер строки проанализирует сообщение и определит, какой объект команды создать, и передаст токенизированную строку в методы команды CanExecute / Execute.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...