用泛型实现开放封闭原则

时间:2016-10-05 08:10:46

标签: c# generics solid-principles

我是初次使用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的聪明成员都能给予的帮助将非常感激。

由于

1 个答案:

答案 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时,您将在工厂字典中注入以生成树节点。您可以通过多种方式构建该字典,而无需重新编译程序集。