Создаю ли я несколько реализаций репозитория, чтобы придерживаться принципа открытия / закрытия? - PullRequest
0 голосов
/ 19 марта 2019

Я мог бы быть совершенно не согласен с этим, так как принцип открытия / закрытия является основным битом SOLID, который я не совсем понимаю. По сути, у меня есть параметр, который я передаю из контроллера в службу. Эта служба получает определенную информацию из хранилища на основе этого параметра. Например:

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

Эти репозитории основаны на абстракциях. Мой вопрос заключается в том, должен ли я как-то создавать несколько репозиториев для этого, и как мне это сделать? Я не вижу никого, кто бы добавил новую опцию в ближайшее время, но это может быть возможно в будущем. Или я оставлю это как оператор switch, а затем создаю Func <> на основе этого свойства, поэтому мне нужно иметь только одну реализацию в хранилище.

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Теоретически switch не нарушает OCP, если вы можете создать подкласс службы для переопределения этого метода. Таким образом, код остается открытым для расширения без необходимости модификации. На практике большинство разработчиков вряд ли последуют этому подходу и вместо этого нарушат OCP, отредактировав switch, добавив новый case.

Поскольку репозиторий уже выставляет различные методы получения в качестве отдельных методов, почему бы не предоставить сигнатуры одинаковых методов через службу?

0 голосов
/ 19 марта 2019

Есть несколько вариантов:

  1. Если это разные типы, вы можете просто использовать перегрузки и подавать все, что у вас есть:

    public Foo Get(DateTime date)
    
    public Foo Get(int number)
    

    Тогда вы просто передадите что-нибудь:

    _repository.Get(lookupValue);
    
  2. Просто переместите коммутатор в репо, который будет обрабатывать более общие сценарии, в том числе, когда есть разные поиски для одного и того же типа(т.е. строка):

    public Foo Get<T>(string lookupType, T lookupValue)
    {
        switch (lookupType){
            case "date": 
                GetByDate(lookupValue);
                break;
            case "serialNumber": 
                GetBySerialNumber(lookupValue);
                break;
         }
    }
    

В обоих случаях предполагается, что вы можете каким-то образом передать значение поиска в общем.Если у вас буквально заканчиваются физические переменные date и 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;
    }
}

Наконец:

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