简体   繁体   English

使用静态方法C#实现命令设计模式

[英]Implementing a Command Design Pattern with static methods C#

I know how to implement a Command Design pattern as follows: 我知道如何实现Command Design模式如下:

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

Say I inherit this ,as an example: 假设我继承了这个,作为一个例子:

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

Problem is to use this ConnectionCommand I need to first instantiate an object, but the commands are context free, so I would prefer to not have to instantiate anything to run the ConnectionCommand's Execute method. 问题是使用这个ConnectionCommand我需要首先实例化一个对象,但命令是无上下文的,所以我宁愿不必实例化任何东西来运行ConnectionCommand的Execute方法。 (PS the ConnectionCommand.Execute() will be run from an event ,in a delegate). (PS,ConnectionCommand.Execute()将从委托中的事件运行)。

How would I recreate this kind of design pattern but allowing the methods to be statically called? 我如何重新创建这种设计模式,但允许静态调用这些方法?

Delegates are C#'s built-in implementation of the command pattern. 代理是C#内置的命令模式实现。 Why re-invent the wheel; 为什么重新发明轮子; use delegates, which support static, pure functions automatically. 使用委托,自动支持静态,纯函数。

So you have an event system and those events invoke delegates. 所以你有一个事件系统,那些事件会调用代理。 You need those delegates to have state though, without creating instances of some class. 您需要这些委托具有状态,而不创建某些类的实例。 That's where closures come in to play. 这就是关闭的地方。 As an example: 举个例子:

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.
    }
}

I've used a 'CommandProcessor' when I've used this pattern: 当我使用这个模式时,我使用了'CommandProcessor':

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

It is then used as such: 然后使用它:

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

It works nicely as your processor can effectively employ a 'pipe and filter' pattern to add cross-cutting concerns. 它可以很好地处理,因为您的处理器可以有效地使用“管道和过滤器”模式来增加横切关注点。

It can be enhanced with generics and overloads for parameters/return values, etc. 它可以通过泛型和参数/返回值的重载等来增强。

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

A link to some of Bob Nystrom's stuff. 链接到一些Bob Nystrom的东西。 Using closures: 使用闭包:

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

A very neat way to do the Command Design pattern in C# using closure and a Factory, similar to an answer above but without state information. 使用闭包和工厂在C#中执行命令设计模式的一种非常简洁的方法,类似于上面的答案但没有状态信息。 Still I've added it for completeness. 我仍然为完整性添加了它。 The Commands.MovePiece can then be subscribed to an appropriate event to get triggered. 然后可以订阅Commands.MovePiece以触发相应的事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM