我是初次使用SOLID所以请原谅我缺乏正确的术语,纠正我,如果需要我想学习: - )
我正在升级库并希望使用Open Closed原则,因为可扩展性而无需修改提供程序。
库的目的是提供基于视图类型的模块列表。根据类型,检索模块的查询和条件是不同的。以下是当前代码的简化版本:
public class ModuleProvider
{
public List<ITreeNode> GetModules(ViewType viewType)
{
switch (viewType)
{
case ViewType.Classes
//build query here that returns List<TreeNode> for classes
return modules;
case ViewType.Queries
//build query here that returns List<TreeNode> for queries
return modules;
}
}
}
我已经读过,使用上面的例子中的switch语句是不好的。我理解为什么,因为如果我要添加一个新的ViewType,GetModules将需要更改。
我认为我必须创建一个具有GetModules函数的接口,然后为每个类创建一个类,即QueryModules和ClassModules类,然后返回特定列表。但是,我仍然坚持上面的提供商将如何改变以支持这一点?我认为我需要使用泛型这是正确的吗?
public interface IModuleProvider
{
List<ITreeNode> GetModules();
}
public class QueryModuleProvider : IModuleProvider
{
public List<ITreeNode> GetModules()
{
return new List<ITreeNode>() { new TreeNode() { Type = "Query Module" } };
}
}
public class ClassModuleProvider : IModuleProvider
{
public List<ITreeNode> GetModules()
{
return new List<ITreeNode>() {new TreeNode() { Type = "Class Module"}};
}
}
我是否在正确的轨道上?任何帮助stackoverflow的聪明成员都能给予的帮助将非常感激。
由于
答案 0 :(得分:0)
这种方法应该相当明显,不一样 - 您已将List<ITreeNode> GetModules(ViewType viewType)
更改为List<ITreeNode> GetModules()
。你现在不是要求一个类用于模块,但你需要在两个类之间做出决定 - 这正是你开始的情况。这是鸡肉或鸡蛋&#34;问题
相反,您应该注入一种动态决定如何构建树节点的方法。
这是一种方法:
public class ModuleProvider
{
private Dictionary<ViewType, Func<List<ITreeNode>>> _factory;
public ModuleProvider(Dictionary<ViewType, Func<List<ITreeNode>>> factory)
{
_factory = factory;
}
public List<ITreeNode> GetModules(ViewType viewType)
{
return _factory[viewType]();
}
}
当您创建ModuleProvider
时,您将在工厂字典中注入以生成树节点。您可以通过多种方式构建该字典,而无需重新编译程序集。