我是否创建存储库的多个实现以遵守开放/封闭原则?

时间:2019-03-19 17:52:37

标签: asp.net-mvc asp.net-core .net-core solid-principles

我可能对此完全不满意,因为打开/关闭原则是我不太了解的SOLID的主要内容。基本上,我有一个从控制器传递到服务的参数。该服务基于该参数从存储库中获取某些信息。例如:

switch(param){
    case "date": 
        _repository.GetByDate(date);
        break;
    case "serialNumber": 
        _repository.GetBySerialNumber(number);
        break;
}

这些存储库基于抽象。我的问题是,是否应该为此创建多个存储库,我将如何处理?我看不到有人会很快添加新选项,但将来可能会出现。还是将其保留为switch语句,然后基于该属性构建Func <>,所以我只需要在存储库中实现一个。

2 个答案:

答案 0 :(得分:0)

有两种选择:

  1. 如果这些类型不同,那么您可以简单地使用重载并将其提供给您:

    A1B 2C3

    然后,您只需传递任何内容:

    public Foo Get(DateTime date)
    
    public Foo Get(int number)
    
  2. 只需将开关移到存储库中,它将处理更通用的情况,包括当针对相同类型(即字符串)的不同查找时:

    _repository.Get(lookupValue);
    

这两个都假设您可以以某种方式通用地传递查找值。如果您实际上以物理public Foo Get<T>(string lookupType, T lookupValue) { switch (lookupType){ case "date": GetByDate(lookupValue); break; case "serialNumber": GetBySerialNumber(lookupValue); break; } } date变量结尾,并且您不知道要传递哪个变量,那么除非您创建某种辅助对象可以将它们引入repo方法:

number

然后:

public class FooLookup
{
    public string Type { get; set; }

    public DateTime Date { get; set; }

    public int Number { get; set; }
}

最后:

public Foo Get(FooLookup lookup)
{
    switch (lookup.Type){
        case "date": 
            GetByDate(lookup.Date);
            break;
        case "serialNumber": 
            GetBySerialNumber(lookup.Number);
            break;
    }
}

答案 1 :(得分:0)

理论上,switch不会违反OCP,只要您可以将服务子类化以覆盖该方法即可。这样,代码无需修改即可保持开放状态以进行扩展。实际上,大多数开发人员不太可能采用该方法,而是通过编辑switch以添加新的case来违反OCP。

由于存储库已经将其各种getter作为单独的方法公开,为什么不通过服务公开完全相同的方法签名?