Путаница с единственной ответственностью в OOP - PullRequest
0 голосов
/ 25 февраля 2020

Давайте рассмотрим следующий пример:

class User
{

}

class FirstUseNotification
{
    function show(User user)
    {
        // check if it was already shown, return if so
        // show a notification
        // mark it as shown in the db or whatever
    }
}

class SomeController
{
    function someMethod()
    {
        firstUseNotification->show(user);
    }
}

Метод show (), кажется, снимает с себя единственную ответственность, выполняя 3 вещи. Итак, я полагаю, что это можно переписать так:

class User
{

}

class FirstUseNotification
{
    function show(User user)
    {
        // show a notification
    }

    function shouldShow(User user)
    {
        // return true if not yet shown
    }

    function markAsShown(User user)
    {
        // flag notification as shown
    }
}

class SomeController
{
    function someMethod()
    {
        if (firstUseNotification->shouldShow(user)) 
        {
            firstUseNotification->show(user);
            firstUseNotification->markAsShown(user);
        }
    }
}

Итак, вот что меня интересует:

  1. Правильно ли я предположить, что во втором примере класс уведомлений теперь все в порядке с принципом единой ответственности?
  2. Все, что происходило в методе show (), ушло, но ... они просто перемещены в метод в контроллере, поэтому это не должно означать, что этот метод контроллера теперь нарушает единственную ответственность? Если так, как это можно сделать, чтобы соответствовать?

1 Ответ

0 голосов
/ 25 февраля 2020

Принцип единой ответственности (SRP) часто выражается в виде цитаты Роберта C. Мартин:

У класса должна быть только одна причина для изменения.

В этом случае цель вашего FirstUseNotification класса - показать уведомление первому пользователь Таким образом, единственная причина, по которой этот класс должен измениться - это изменение этой цели; и это одна из причин, поэтому SRP удовлетворен.

Обратите внимание, что это определение относится к классу, а не к методу. Тем не менее, разбиение этого метода на три метода, вероятно, нарушает SRP, потому что если пользователю этого класса нужно вызвать три метода вместо одного, то этот пользовательский класс несет ответственность за проверку, показывать ли уведомление и отмечая пользователя, как показано, в дополнение к собственной ответственности класса пользователя. Ответственность FirstUseNotification заключается в том, чтобы «показывать уведомление новичку», а не в предоставлении API, который позволяет другим классам делать это, когда это не входит в их обязанности.

На практике FirstUserNotification класс может иметь другие причины для изменения, если сведения о том, как он показывает уведомление или обращается к базе данных, изменяются В идеале этого можно избежать, если иметь стабильные интерфейсы для уведомлений и классов базы данных, чтобы изменения в этих классах не требовали изменений в FirstUseNotification или других классах, которые показывают уведомления и / или получают доступ к базе данных. На практике это не всегда достигается на 100%, и в этом случае класс FirstUseNotification может иметь некоторые обязанности, связанные с отображением уведомления или доступом к базе данных. Но в теории, если эти другие классы должным образом справляются со своими обязанностями, у этого класса есть только одна причина для изменения.

...