2015-06-02 51 views
3

我知道如何實現一個命令設計模式如下:實現靜態方法C#中的命令設計模式

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

說我繼承了這一點,作爲一個例子:

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

問題是使用此ConnectionCommand我需要首先實例化一個對象,但這些命令是上下文無關的,所以我寧願不必實例化任何內容來運行ConnectionCommand的Execute方法。 (參見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方法,他們有時還有Property列表,私有方法等等。我想要一個Command基類來允許任何這樣的命令從事件中執行,並且這將使用該Command類來完成一堆事情。 Silimar對賈斯汀哈維說的低潮。 –

+0

這不會需要實例化'ConnectionCommand'類嗎? –

+0

是的,是的,它會:P。這正是我的問題。 –

0

我用的時候我用這個模式的 'CommandProcessor':

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

它隨後被用作這樣的:

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

它的工作原理很好,因爲您的處理器可以有效地採用「管道和過濾器」模式來增加橫切關注點。

它可以與仿製藥和過載的參數/返回值來增強等

+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(); 
    } 
} 

一個非常簡潔的方式使用封閉和工廠,類似於上面,但沒有狀態信息的答案做在C#中的命令設計模式。我仍然爲了完整而添加它。 Commands.MovePiece然後可以被訂閱適當的事件來觸發。