公开可用操作的正确模式
Correct pattern for exposing available actions
我有一个 class 可以对给定对象执行许多分析和 return 返回结果集:
public class AnalyserClass
{
private SomeObject _someObject;
public AnalyserClass(SomeObject someobject)
{
_someObject = someobject;
}
public IEnumerable<Result> DoA
{
//checks A on someObject and returns some results
}
public IEnumerable<Result> DoB
{
//checks B on someObject and returns some results
}
//etc
}
public class Result
{
//various properties with result information
}
public class SomeObject
{
//this is the object which is analysed
}
我想在 WinForm 的 CheckedListBox 中公开这些操作(DoA、DoB 等)。然后用户将勾选 s/he 想要执行的操作,然后单击 运行 按钮。
理想情况下,我希望将操作公开为动态的 - 因此,如果我在 AnalyserClass 中开发一个新操作,它将自动显示并可从 WinForm 执行,而无需在其他任何地方更改任何代码。
我是一个相当新的 C# 程序员。我一直在研究如何最好地构建它,但我对各种模式以及哪种模式最适合使用感到有点困惑。
首先我阅读了 MVVM 模式,但这似乎比这里要求的更复杂,我不明白模型是什么。
然后我看了Command模式。但据我所知,我必须为每个动作(有很多)创建一个 class 包装器,这会非常耗时并且看起来有点麻烦(在多个地方更改代码,所以不'dynamic')。我也不明白如何从命令 classes 构建复选框列表。这似乎是我能找到的最合适的模式,但由于我缺乏经验,我不确定。
非常感谢您的指导。
这里我不会选择Reflection,因为它让不必要的事情变得复杂。
此外,使用您当前的方法,每次需要新的分析器工具时,您都需要使用新功能扩展 AnalyserClass
,并且:
- 打破了SOLID的"open-closed"原则,
- 打破了SOLID的"single responsibility"原则,
- 使您的 class 太大且难以维护。
我会在您的 AnalyserClass
中介绍一组支持的操作:
class AnalyserClass
{
public IEnumerable<IAnalyzer> Analyzers { get; private set; }
}
...其中 IAnalyzer
界面描述了您的操作:
interface IAnalyzer
{
string Description { get; } // this is what user will see as the action name
Result Perform(SomeObject input);
}
然后您可以根据需要在各种 class 中实现 IAnalyzer
,甚至在不同的模块等中。
唯一的开放点是 - 如何将所有 IAnalyzer
个实例添加到您的 AnalyzerClass.Analyzers
集合中?
嗯:
- 你可以使用 DI 框架(例如 MEF)让它自动发现所有东西,
- 您可以通过 DI 手动注入它们,
- 您可以使用反射并手动扫描类型,
- 您可以手动添加它们,例如在
AnalyzerClass
的构造函数中(简单但不推荐)
- 等等...
我有一个 class 可以对给定对象执行许多分析和 return 返回结果集:
public class AnalyserClass
{
private SomeObject _someObject;
public AnalyserClass(SomeObject someobject)
{
_someObject = someobject;
}
public IEnumerable<Result> DoA
{
//checks A on someObject and returns some results
}
public IEnumerable<Result> DoB
{
//checks B on someObject and returns some results
}
//etc
}
public class Result
{
//various properties with result information
}
public class SomeObject
{
//this is the object which is analysed
}
我想在 WinForm 的 CheckedListBox 中公开这些操作(DoA、DoB 等)。然后用户将勾选 s/he 想要执行的操作,然后单击 运行 按钮。
理想情况下,我希望将操作公开为动态的 - 因此,如果我在 AnalyserClass 中开发一个新操作,它将自动显示并可从 WinForm 执行,而无需在其他任何地方更改任何代码。
我是一个相当新的 C# 程序员。我一直在研究如何最好地构建它,但我对各种模式以及哪种模式最适合使用感到有点困惑。
首先我阅读了 MVVM 模式,但这似乎比这里要求的更复杂,我不明白模型是什么。
然后我看了Command模式。但据我所知,我必须为每个动作(有很多)创建一个 class 包装器,这会非常耗时并且看起来有点麻烦(在多个地方更改代码,所以不'dynamic')。我也不明白如何从命令 classes 构建复选框列表。这似乎是我能找到的最合适的模式,但由于我缺乏经验,我不确定。
非常感谢您的指导。
这里我不会选择Reflection,因为它让不必要的事情变得复杂。
此外,使用您当前的方法,每次需要新的分析器工具时,您都需要使用新功能扩展 AnalyserClass
,并且:
- 打破了SOLID的"open-closed"原则,
- 打破了SOLID的"single responsibility"原则,
- 使您的 class 太大且难以维护。
我会在您的 AnalyserClass
中介绍一组支持的操作:
class AnalyserClass
{
public IEnumerable<IAnalyzer> Analyzers { get; private set; }
}
...其中 IAnalyzer
界面描述了您的操作:
interface IAnalyzer
{
string Description { get; } // this is what user will see as the action name
Result Perform(SomeObject input);
}
然后您可以根据需要在各种 class 中实现 IAnalyzer
,甚至在不同的模块等中。
唯一的开放点是 - 如何将所有 IAnalyzer
个实例添加到您的 AnalyzerClass.Analyzers
集合中?
嗯:
- 你可以使用 DI 框架(例如 MEF)让它自动发现所有东西,
- 您可以通过 DI 手动注入它们,
- 您可以使用反射并手动扫描类型,
- 您可以手动添加它们,例如在
AnalyzerClass
的构造函数中(简单但不推荐) - 等等...