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

问题描述 投票:0回答:2

我可以完全放弃这个,因为开放/封闭原则是SOLID的主要部分,我不太了解。基本上,我有一个参数,我从控制器传递给服务。该服务基于该参数从存储库获取某些信息。例如:

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

这些存储库基于抽象。我的问题是,我应该以某种方式为此创建多个存储库,我将如何解决这个问题?我没有看到任何人很快添加新选项,但未来可能会有可能。或者我将其保留为switch语句,然后基于属性构建Func <>,因此我只需要在存储库中有一个实现。

asp.net-mvc asp.net-core .net-core solid-principles
2个回答
0
投票

有几种选择:

  1. 如果这些是不同的类型,那么你可以简单地使用重载并提供它,无论你有什么: public Foo Get(DateTime date) public Foo Get(int number) 然后,你只需传递任何东西: _repository.Get(lookupValue);
  2. 只需将交换机移动到repo中,它将处理更多通用场景,包括对同一类型(即字符串)的不同查找时: public Foo Get<T>(string lookupType, T lookupValue) { switch (lookupType){ case "date": GetByDate(lookupValue); break; case "serialNumber": GetBySerialNumber(lookupValue); break; } }

这两个都假设您可以以某种方式通过查找值。如果你真的以物理datenumber变量结束,并且你不知道传入哪个,那么你就会在行动中遇到切换,除非你创建某种辅助对象来运送它们在repo方法中:

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;
    }
}

最后:

_repository.Get(new FooLookup
{
    Type = param,
    Date = date,
    Number = number
});

0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.