使用泛型实现开放封闭原则
Posted
技术标签:
【中文标题】使用泛型实现开放封闭原则【英文标题】:Implementing open closed principle using generics 【发布时间】:2016-10-05 08:10:46 【问题描述】:我是使用 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";
我在正确的轨道上吗?非常感谢 *** 的聪明成员提供的任何帮助。
谢谢
【问题讨论】:
第二个代码 sn-p 中未涵盖的您需要什么? 这种方法应该很明显,它不一样 - 您已将List<ITreeNode> GetModules(ViewType viewType)
更改为 List<ITreeNode> GetModules()
。您现在不是要求一个班级提供模块,而是需要在两个班级之间做出决定——这正是您开始时的情况。这是一个“先有鸡还是先有蛋”的问题。
查找策略模式。这通常是 switch 语句的答案
【参考方案1】:
这种方法应该很明显,它不一样 - 您已将 List<ITreeNode> GetModules(ViewType viewType)
更改为 List<ITreeNode> GetModules()
。您现在不是要求一个班级提供模块,而是需要在两个班级之间做出决定——这正是您开始时的情况。这是一个“先有鸡还是先有蛋”的问题。
相反,您应该注入一种动态决定如何构建树节点的方法。
这是一种方法:
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
时,您将在工厂字典中注入以生成树节点。您可以通过多种方式构建该字典,而无需重新编译程序集。
【讨论】:
以上是关于使用泛型实现开放封闭原则的主要内容,如果未能解决你的问题,请参考以下文章