2015-06-02 54 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然后可以被订阅适当的事件来触发。