gpt4 book ai didi

c# - 需要了解如何处理 Winforms 应用程序中的可变任务组

转载 作者:行者123 更新时间:2023-11-30 15:46:13 24 4
gpt4 key购买 nike

我正在努力解决如何在我的应用程序中分离操作。我基本上有一个表单,用户可以选择要执行的操作。有些 Action 是独立的,很容易进入我按顺序执行的队列。但是,有些 Action 需要多个相关 Action ,主要 Action 需要先处理其他任务:

Create Website
- DoesWebsiteExists (Validation)
- CreatePhyiscalDir
- CreateWebsite
- CreateVirDirectories

所有这些 Action 都是分开的,彼此不知道。

最初,在我将验证与操作分开之前,我传递了一个包含所有相关/需要的设置以执行任何操作的设置对象和一个我迭代并在每个操作上调用 Execute() 方法的队列。

 Queue<IAction> Actions
[0] = CreateDirectory.Execute()
[1] = CreateWebsite.Execute()

但现在我已经剥离了所有这些 Action ,我不确定如何重新组装它们。

我有列表列表吗?如果该 Action 是一个独立的 Action ,那么它只是一个包含 1 个元素的列表?如果它是一个需要 4 个 Action (4 个不同的对象)的 Action ,它会是一个包含 4 个元素的列表吗?

要在其中添加一个附加层 - 有时主要操作可能需要或不需要操作,具体取决于表单上选择的选项。例如,如果用户选择在 IIS 中创建一个应用程序池,它可能在列表中,也可能不在列表中,并想出一种方法来确定列表的优先级。

有什么想法吗?

最佳答案

你的 IAction接口(interface)(不要与 Action Delegate 混淆)看起来很像 Command Pattern 的实现。 .过去,当我想将命令组合在一起时 (.NET v1.0),我会创建一个 Composite模式来创建复合命令或在您的情况下是复合操作。所以它的实现细节将有一个 Add 方法和一个 Execute 看起来像..

public CompositeAction : IAction
{
private ActiondCollection Action;

void Add(Action action)
{
Action.Add(action);
}

void Execute()
{
foreach(Action action in Actions)
{
action.Execute();
}
}
}

这符合你list of lists的想法。

你可以这样做,但由于 Execute 返回 void ,停止命令链工作的唯一方法是抛出异常或使用一些奇怪的耦合(从 DoesWebSiteExist 更新一些 IsValid 值,然后在每个 Action 中检查该值)

相反,您可以实现 Chain of responsibility这将更干净地处理这个问题。

另一种选择,如果您可以修改现有方法以仅返回一个 bool 值,那么使用 Func 就可以轻松获得您想要的结果

这里的好处是只要一个方法返回一个 bool 它就可以参与这个结构。不好的是它不是通过接口(interface)强制执行的,所以这些方法没有明确的目的,所以它有一些代码味道。

namespace Test
{
class Program
{
//Change this value to show how the Actions bail when you DoesWebsiteNotExists
//returns false
static bool isvalid = true;
static void Main(string[] args)
{
List<System.Func<bool>> MainActions = new List<System.Func<bool>>();

List<System.Func<bool>> CompositeActions = new List<System.Func<bool>>();

MainActions.Add(() => NonCompositeAction());

//Probably want a builder here.
CompositeActions.Add(() => DoesWebsiteNotExists());
CompositeActions.Add(() => CreatePhyiscalDir());
CompositeActions.Add(() => CreateVirDirectories());
CompositeActions.Add(() => CreateWebsite());

MainActions.Add(() => ExcuteCompositeActions(CompositeActions));

foreach (Func<bool> action in MainActions)
action.Invoke();



}


static bool ExcuteCompositeActions(List<System.Func<bool>> Actions)
{



bool Success = true;
foreach (Func<bool> action in Actions)
{
if (!action.Invoke())
{
Success = false;
break;
}

}
return Success;
}

static bool NonCompositeAction()
{
Console.WriteLine("NonCompositeAction");
return true;
}

static bool DoesWebsiteNotExists()
{
Console.WriteLine("DoesWebsiteExists");
return isvalid;
}
static bool CreatePhyiscalDir()
{
Console.WriteLine("CreatePhyiscalDir");
return true;
}
static bool CreateWebsite()
{
Console.WriteLine("CreateWebsite");
return true;
}
static bool CreateVirDirectories()
{
Console.WriteLine("CreateVirDirectories");
return true;
}






}

}

至于确定优先级,我会预先确定,而不是先建立再确定优先级。

更新 阐明List<Func<bool>中的方法可以来自任何地方。例如,如果你有这门课

public class CreatePhyiscalDir
{

public bool Execute()
{
Console.WriteLine("CreatePhyiscalDir");
return true;
}
}

你可以把上面的改成

    CreatePhyiscalDir cpd = new CreatePhyiscalDir();
CompositeActions.Add(() => DoesWebsiteExists());
CompositeActions.Add(() => cpd.Execute());

只要您的 cpd 在范围内,这就会起作用。

我想强调的是 List<Func<bool>实力是……

  1. 它允许您通过调用返回 bool 值的方法来创建结构,几乎可以是任何值。这在您拥有预先存在的代码库的情况下特别有用。
  2. 它创建了一个依赖关系,即除非前一个 Action 成功,否则不会执行下一个 Action 。

但是弱点是...

  1. 您可能会发现自己编写的方法 return true;只是为了适应原本不会存在的结构。
  2. 方法或类之间的关系一点也不清楚。

所以你有三个选项,一个是责任链或管道的实际实现,一个伪管道实现,如 List<Func<bool>>解决方案或像 SnOrfus 答案这样的复合 Action 。您选择哪一个可能取决于您到目前为止所写的内容以及您需要更改的内容。

最后一个想法。您可能想先决定,是每个 Action 决定是否应该执行下一个操作,还是循环代码决定。它可能会告知您如何实现。

关于c# - 需要了解如何处理 Winforms 应用程序中的可变任务组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4474525/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com