首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在命令模式中的命令与C#之间共享相同的上下文?

如何在命令模式中的命令与C#之间共享相同的上下文?
EN

Stack Overflow用户
提问于 2016-06-17 14:24:39
回答 7查看 2.7K关注 0票数 9

我在我的应用程序中实现了命令模式(以一种多支持的方式)。

结构:

代码语言:javascript
复制
class MultiCommand : BaseCommand

abstract class BaseCommand : ICommand

工艺流程:

代码语言:javascript
复制
   var commandsGroup = new MultiCommand(new List<ICommand>()
            {
                new Command1(),
                new Command2(),
                new Command3(),
            });

   commandsGroup.Execute()

现在,假设在Command1中更改了一个somethingID,我将在Command2中使用这个新值.而且,在整个执行过程中,还有许多--其他属性--对象--受到影响。

此外,在任何命令中,只要使用上下文对象,都应该有一些接口实现,如下所示:

代码语言:javascript
复制
Context.ServerController.something();

IServerController的实例化将在multiCommandGroup初始化之前进行。

对于组中的所有命令,我如何拥有这样一个共享的上下文

上下文类的示例:

代码语言:javascript
复制
public class CommandContext
{
    public IServerController ServerController;
    public RequiredData Data { get; set; }

    public CommandContext(){}
}

重要的最小实现代码是这里

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2016-06-17 15:44:19

1)如果要保留此接口,则必须将此上下文作为构造函数参数传递:

代码语言:javascript
复制
new MultiCommand(new List<ICommand>()
            {
                new Command1(context),
                new Command2(context),
                new Command3(context),
            })

2)作为另一种选择,您可以接受委托列表而不是命令列表。MultiCommand将如下所示:

代码语言:javascript
复制
class MultiCommand : ICommand
{
    public MultiCommand(List<Func<Context, Command>> commands, Context context)

}

这几乎是一样的,除非MultiCommand负责所有命令共享相同的上下文。

3)看起来像MultiCommand中的命令依赖于先前命令的结果。在这种情况下,命令模式可能不是最好的。也许您应该尝试在这里实现中间件链?

代码语言:javascript
复制
interface IMiddleware<TContext>
{
   void Run(TContext context);
}

class Chain<TContext>
{
    private List<IMiddleware<TContext>> handlers;

    void Register(IMiddleware<TContext> m);

    public void Run(TContext context)
    {
        handlers.ForEach(h => h.Run(context));
    }
}
票数 5
EN

Stack Overflow用户

发布于 2016-06-17 14:30:50

您可以在BaseCommand类(及其派生类)上有一个构造函数,该构造函数可以接受某种类型的Context类。当实例化属于同一组的命令时,可以为它们提供所有相同的上下文对象。也许是这样:

代码语言:javascript
复制
public class CommandContext
{
    // The object that will be the target of the commands' actions.
    public object Data { get; set; }

    // ... any other properties that might be useful as shared state between commands...
}

public abstract class BaseCommand : ICommand
{
    protected CommandContext Context { get; private set; }

    public BaseCommand(CommandContext ctx)
    {
        Context = ctx;
    }
}

public class ChangeSomethingIDCommand : BaseCommand
{
    public ChangeSomethingIDCommand(CommandContext ctx) : base(ctx)
    { }

    public void Execute()
    {
        var target = (SomeDomainClass)Context.Data;
        target.SomethingID++;
    }
}

// Elsewhere in your code (assuming 'myTargetDomainClassInstance' is
// a SomeDomainClass instance that has been instantiated elsewhere and
// represents the object upon which the commands will do work):
var ctx = new CommandContext { Data = myTargetDomainClassInstance };
var commandGroup = new MultiItemCommand(ctx, new List<ICommand>
    {
        new ChangeSomethingIDCommand(ctx),
        new Command2(ctx),
        new Command3(ctx)
    });

commandGroup.Execute();
票数 3
EN

Stack Overflow用户

发布于 2016-06-17 14:31:28

我建议把一些东西变成通用的。下面是一个超级简单的例子。

代码语言:javascript
复制
class MultiCommand<TContext>  
{
    List<Command<TContext>> Commands;
    TContext Context;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37884056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档