2015-06-02 5 views
3

Я знаю, как реализовать шаблон Command Design следующим образом:Реализация паттерна Command Design с статические методы C#

public abstract class Command 
{ 
    public abstract void Execute(string someString); 
} 

Say I унаследовать это, как пример:

public class ConnectionCommand : Command 
{ 
    public override void Execute(string connectionString) 
    { 
     ...do some stuff here...; 
    } 
} 

Проблема заключается в используйте этот ConnectionCommand Мне нужно сначала создать экземпляр объекта, но команды являются свободными от контекста, поэтому я бы предпочёл не создавать экземпляр ничего для запуска метода Execute ConnectionCommand. (P.S. ConnectionCommand.Execute() будет запущен из события в делегате).

Как бы я воссоздал этот шаблон дизайна, но позволил статическим вызовам методов?

+0

Что здесь означает «контекстно-свободный»? –

+0

Они не требуют конкретной информации о экземпляре для выполнения. Они просто вызваны из любого другого класса, и они делают что-то, не требуя ничего знать о классе, который их называет. Может использоваться как статический метод. –

+2

Кажется, что у вас есть абсорбирующая абстракция: ваш абстрактный класс имеет параметр 'string connectionString', который уже подразумевает какую-то команду соединения. – Philippe

ответ

8

Делегаты - это встроенная реализация шаблона команды C#. Зачем изобретать колесо; используйте делегаты, которые автоматически поддерживают статические, чистые функции.

У вас есть система событий, и эти события вызывают делегатов. Тем не менее, эти делегаты должны иметь состояние, не создавая экземпляров какого-либо класса. Вот тут и появляются замыкания. В качестве примера:

public class SomeClass 
{ 
    public static CreateCommand(SomeType state, SomeEventHandler eventHandler) 
    { 
     eventHandler += (s, e) => MyDelegate(state, s, e); 
    } 

    private static void MyDelegate(SomeType state, object sender, EventArgs e) 
    { 
     // do something with state, when the event is fired. 
    } 
} 
+0

Я согласен с этим, проблема в том, что некоторые из команд не просто имеют свой метод Execute, они иногда имеют списки свойств, частные методы и т. Д. Я хотел, чтобы базовый класс Command позволял любой такой команде выполняться из события, и это будет использовать этот класс Command, чтобы сделать кучу вещей. Силимар, что сказал Джастин Харви. –

+0

Разве это не потребует создания класса 'ConnectionCommand'? –

+0

Да, да это было бы: P. Это именно моя проблема. –

0

Я использовал 'CommandProcessor', когда я использовал этот шаблон:

class CommandProcessor 
{ 
    static void Execute(ICommand command) 
    { 
     command.Execute(); 
    } 
} 

Затем она используется в качестве таковых:

CommandProcessor.Execute(new ConnectionCommand {PropertyX = 1, ProperyY = 2}); 

Он работает так как ваш процессор может эффективно использовать шаблон «pipe and filter», чтобы добавить сквозные проблемы.

может быть повышен с обобщениями и перегрузками для значений параметров/возврата и т.д.

+0

Кажется, что это может помочь решить мою проблему. За исключением того, что он все еще требует создания экземпляра, но, по крайней мере, он будет обновлять мой текущий код. –

+0

Он опрятный. Я использую общую версию с Castle Windsor и позволяю ей обрабатывать мои экземпляры. Вы заканчиваете: CommandProcessor.Execute (); ' –

+0

Оба этих ответа кажутся очень хорошими, я попробую оба и посмотрю, какой из них лучше подходит для моего кода (пока не могу, бит занятый). –

0

http://journal.stuffwithstuff.com/2009/07/02/closures-and-the-command-pattern/

ссылка на некоторые вещи Боба Нюстрёма. Использование укупорочные:

static class Commands 
{ 
    // create a command to move a piece 
    public static Action MovePiece(Piece piece, int x, int y) 
    { 
     return() => piece.MoveTo(x, y); 
    } 
} 

class Program 
{ 
    public static Main(string[] args) 
    { 
     // ui or ai creates command 
     var piece = new Piece(); 
     var command = Commands.MovePiece(piece, 3, 4); 

     // chess engine invokes it 
     command(); 
    } 
} 

Очень аккуратный способ сделать шаблон Command Design в C# с помощью закрытия и завод, подобный ответ выше, но без информации о состоянии. Тем не менее я добавил его для полноты. Затем Commands.MovePiece может быть подписана на соответствующее событие для запуска.

Смежные вопросы