В чем заключается использование принципа единой ответственности?

Я пытаюсь понять принцип единой ответственности, но мне трудно понять эту концепцию. Я читаю книгу «Паттерны проектирования и передовой опыт в Java», написанные Лучианом-Полем Торже; Адрианом Янкулеску; Камалмитом Сингхом.

В этой книге я читаю главу о принципе единственной ответственности, где у них есть класс машины, как показано ниже:

В чем заключается использование принципа единой ответственности?

Они сказали, что в Car есть как логика автомобиля, так и операции с базой данных. В будущем, если мы захотим изменить базу данных, нам нужно будет изменить логику базы данных и, возможно, также потребуется изменить логику автомобиля. Наоборот...

Решением было бы создать два класса, как показано ниже:

В чем заключается использование принципа единой ответственности?

Мой вопрос в том, что даже если мы создадим два класса, давайте рассмотрим, что мы добавляем новое свойство под названием «цена» к классу CAR [или меняем свойство «модель» на «carModel»], тогда вы не думаете, что нам также нужно обновить Класс CarDAO, например, изменение SQL или так далее.

Так в чем же здесь польза от SRP?

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
5
0
852
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Для добавления нового свойства вам нужно изменить оба класса, только если это свойство нужно сохранить в базе данных. Если это свойство используется в бизнес-логике, вам не нужно изменять DAO. Также, если вы меняете свою базу данных от одного поставщика к другому или с SQL на NoSQL, вам придется вносить изменения только в класс DAO. И если вам нужно изменить какую-то бизнес-логику, вам нужно изменить только класс Car.

Проще говоря, SRP помогает нам СНИЗИТЬ влияние изменений. Я прав ?

vicky 09.09.2018 20:41

Да, чтобы уменьшить влияние, чтобы сделать параллельную разработку несколькими разработчиками быстрее и проще (избегайте конфликтов слияния, если один разработчик работает с классом Car, а другой - с классом CarDAO)

Ivan 09.09.2018 20:44
Ответ принят как подходящий

Отличный вопрос.

Во-первых, имейте в виду, что это упрощенный пример из книги. Читатель должен немного расширить это и представить более сложные сценарии. Во всех этих сценариях представьте, что вы не единственный разработчик в команде; вместо этого вы работаете в большой команде, и взаимодействие между разработчиками часто принимает форму согласования интерфейсов классов т.е. API, общедоступных методов, общедоступных атрибутов, схем баз данных. Кроме того, вам часто придется беспокоиться об откатах, обратной совместимости и синхронизации выпусков и развертываний.

Предположим, например, что вы хотите поменять базу данных, скажем, с MySQL на PostgreSQL. С помощью SRP вы повторно реализуете CarDAO, измените любой используемый диалектный SQL и оставите логику Car нетронутой. Однако вам, возможно, придется внести небольшое изменение, возможно, в конфигурацию, чтобы сообщить Car использовать новый PostgreSQL DAO. Разумная структура DI упростит это.

Предположим, в другом примере вы хотите делегировать CarDAO другому разработчику для интеграции с memcached, чтобы чтение, в конечном итоге согласованное, было быстрым. Опять же, этому разработчику не нужно ничего знать о бизнес-логика в Car. Вместо этого им нужно только работать с методами CRUD CarDAO и, возможно, объявить еще несколько методов в API CarDAO с различными гарантиями согласованности.

Предположим, что в еще одном примере ваша команда нанимает инженера по базам данных, специализирующегося на соблюдении законодательства. В рамках подготовки к предстоящему IPO перед инженером баз данных стоит задача вести журнал аудита всех изменений во всех таблицах 35 баз данных компании. Благодаря SRP нашему бесстрашному администратору баз данных не придется беспокоиться ни о каком из бизнес-логика, использующем любую из наших таблиц; вместо этого их магия отслеживания мутаций может быть ловко введена в DAO повсюду, используя декораторы или другие методы программирования аспектов. (Кстати, это также можно сделать с другой стороны интерфейса SQL.)

Хорошо, еще один последний - предположим, что теперь в команду включен системный инженер, и ему поручено сегментировать эти данные по нескольким регионам (центрам обработки данных) в AWS. Этот инженер мог бы пойти еще дальше в SRP и добавить компонент, единственная роль которого - сообщать нам для каждого идентификатора домашний регион каждого объекта. Каждый раз, когда мы выполняем межрегиональное считывание, новый компонент запускает счетчик; Каждую неделю автоматизированный инструмент переносит данные, часто считываемые из разных регионов, в новый домашний регион, чтобы уменьшить задержку.

А теперь давайте продолжим наше воображение и предположим, что бизнес процветает - внезапно вы работаете в компании из списка Fortune 500 с несколькими отделами в разных странах. Бизнес-аналитики из финансового отдела хотят использовать вашу таблицу для отображения квартального роста продаж автомобилей в своих отчетах для инвесторов после IPO. Вместо того, чтобы предоставлять им доступ к Car (поскольку логика, используемая для отчетности, может отличаться от логики, используемой для подготовки данных для рендеринга в веб-интерфейсе), вы потенциально можете создать интерфейс только для чтения для CarDAO с коротким списком тщательно подобранные общедоступные атрибуты, которые теперь необходимо поддерживать вне границ отделов. Не дай бог вам придется переименовать один из этих атрибутов: будьте готовы к трехмесячному плану заката, множеству печальных дашбордов и ночной эскалации. (И, пожалуйста, не предоставляйте им прямой доступ к реальной таблице SQL, потому что неявное предположение будет заключаться в том, что вся таблица является открытым интерфейсом в.) К сожалению, мои шрамы могут быть видны.

Следствием этого является то, что, если вам нужно изменить бизнес-логика в Car (скажем, добавить метод, который вычисляет более низкую продажную цену каждой Tesla после неудобного отзыва), вы не прикасаетесь к CarDAO, поскольку if car.brand == 'Tesla; price = price * 0.6 не имеет к нему никакого отношения. доступ к данным.

Дополнительное чтение: CQRS

Спасибо за подробное объяснение. Чтобы упростить задачу, я добавляю свойство в класс Car. Мне также нужно внести изменения в CarDAO, но влияние будет меньше по сравнению с предыдущим. Я правильно понимаю?

vicky 09.09.2018 20:39

Да, это правильно. Как следствие, если вам нужно изменить бизнес-логику, вы не будете трогать DAO.

James Lim 09.09.2018 20:42

Да, а как насчет модели? Если я внесу какие-то изменения в модель, мне также придется изменить DAO, верно?

vicky 09.09.2018 20:43

Если под model вы имели в виду Car.model, то вы можете переименовать столбцы в CarDAO, не меняя интерфейс Car (и наоборот).

James Lim 09.09.2018 20:46

«Модель» Я имею в виду сам класс автомобиля, например, переименование свойства или добавление дополнительных свойств.

vicky 09.09.2018 20:49

О, я вижу. В этом случае некоторые изменения должны быть внесены с обеих сторон, тогда как с SRP есть вероятность, что некоторые изменения должны быть сделаны только с одной стороны. Например, вы можете добавить атрибут decade к Car, производный от Car.year, без изменений в CarDAO.

James Lim 09.09.2018 20:52

Прохладный. Понятно !!

vicky 09.09.2018 20:55

Не могли бы вы ответить еще раз?) Цитата из вики «В качестве примера рассмотрим модуль, который компилирует и печатает отчет. Представьте, что такой модуль можно изменить по двум причинам. Во-первых, может измениться содержание отчета. Во-вторых, формат отчет может измениться. Эти две вещи меняются по очень разным причинам: одна существенная, а другая косметическая. Принцип единственной ответственности гласит, что эти два аспекта проблемы на самом деле являются двумя отдельными обязанностями "Итак, если роль пользователя нуждается в каком-то специальном столбце для отчета мне нужно делать двойные классы с почти таким же кодом только с новым столбцом?

Sultan Zhumatayev 07.05.2020 21:33

Принцип единой ответственности, как заявил Роберт К. Мартин, означает, что

A class should have only one reason to change.

Соблюдение этого принципа обычно приводит к меньшим и очень связным классам, что, в свою очередь, означает, что меньше людей должно работать с этими классами одновременно, и код становится более надежным.

В вашем примере разделение логики доступ к данным и бизнес-логика (расчет цены) означает, что вы с меньшей вероятностью нарушите другую при внесении изменений.

Другие вопросы по теме