Принцип единой ответственности в ООП - PullRequest
9 голосов
/ 14 сентября 2011

В моем проекте приложения я обычно сопоставляю объекты с важными таблицами в базе данных. Затем объекты обрабатывают все, что относится к этим данным (включая таблицы связей). Так, например, я построил объект Activity со свойствами, такими как name и due_date, методы, такие как load() и save(), а также методы, такие как getParent(), getContributors() и getTeam(), которые вернуть (массивы) другие объекты. Это «плохой» ООП, потому что он нарушает принцип единой ответственности?

Ответы [ 5 ]

5 голосов
/ 14 сентября 2011

Это зависит от ситуации и от того, какой именно код у вас есть: ваш дизайн может касаться нескольких обязанностей и при этом быть довольно приятным ООП и обслуживаемым.

Обрабатываете ли вы load() и save() в каждом классе с аналогичным кодом ? Или вы делегируете задачу в load() и save() другим объектам, которые используются для этой функции в нескольких классах? Это будет наполовину меньше, чем после SRP, и все равно будет соответствовать вашему замыслу.

Если нет, ваш код действительно кажется немного вонючим. Чтобы проверить, охватывает ли он несколько обязанностей, спросите себя: что может вызвать изменения в моем классе? В вашей ситуации я бы по крайней мере попытался рефакторинг аналогичного кода в load() и save() в разных классах для достижения ситуации, описанной выше, так что

  • значительно улучшена ремонтопригодность,
  • вам по-прежнему не нужно менять код своих клиентов.
1 голос
/ 14 сентября 2011

То, что вы описываете, является ActiveRecord, и хорошо известно, что он нарушает SRP.Кроме того, ActiveRecord хорошо работает только тогда, когда строки таблицы близко соответствуют объекту.Как только Несоответствие Импеданса становится слишком большим, это усложнит изменения в системе позже.

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

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

1 голос
/ 14 сентября 2011

Может быть, я просто пну в темноте с этим (потому что я не эксперт), но:

Методы load () и save () внутри объектов домена называются Active Record ( Другое описание ).Это неплохо (хотя мне это не нравится), потому что у людей, которые, возможно, будут работать после вас или с вами, будет меньше проблем с поиском способов сохранения этих объектов.

О других методах.Это не так уж плохо, если он находится в домене объектов и представляет поведение объектов.Если хорошо спроектирован, это может быть очень хорошо. Домен-управляемый дизайн поощряет использование модели расширенного домена, которая противоположна модели анемичного домена.Модель анемичного домена имеет доменные объекты, которые имеют только свойства и методы получения и установки.Так что, пока он находится в области вашего объекта, добавление в него дополнительных методов не считается плохим.

Это насколько я понимаю, это понятие из книг и статей, которые я прочитал ..

Надеюсь, это поможет ..

1 голос
/ 14 сентября 2011

Ну, на этом этапе сложно сказать. Вы могли бы сдать весь класс, но ..

Да, похоже, плохой ООП. У вас есть тот же класс, отвечающий за взаимодействие с базой данных и доменной логикой. Это создает две совершенно разные причины для изменения класса.

Вы могли бы получить выгоду от изучения DataMapper pattern.

0 голосов
/ 14 сентября 2011

Я думаю, что важно перестать думать, что Модель должна быть только слоем между логикой и базой данных.Модель может работать с базой данных и с другими моделями, вся логика должна быть в Моделях.
Я думаю, что есть два способа:

  1. Ваша Модель может вернуть массив идентификаторов в методе getContributors(), иВы можете создать новый объект (возможно, Factory), который преобразует эти идентификаторы в объекты.
  2. ваша модель может возвращать массив объектов, но без использования ключевого слова new, но через контейнер фабрики или зависимостей (я предпочитаюDC).
...