Действительно ли сеттеры и геттеры нарушают SRP?

Недавно я прочитал статью, в которой описывается, как они явно могут нарушить Рекомендуемая цена. И вот я совсем запутался, потому что давно писал одиночные классы с сеттерами и геттерами.

Кроме того, я нашел это, но это не имеет ничего общего с SRP

Ну, на первый взгляд, и геттеры, и сеттеры не нарушают принцип единой ответственности, потому что их логика "принадлежит" только текущему классу. Они могут получить доступ/записать членов класса, которые «служат» одной цели. Отлично.

Но подождите, давайте сначала определим основные термины:

Доступ к данным = как сеттеры, так и геттеры

Обработка данных = обработка данных, такие операции, как CRUD, проверка и т. д.

Если это так, то у нас есть две разные обязанности в рамках одного класса, что нарушает SRP.


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

class DA { // <- Data Access
  public string getName() {
      return this.name;
  }

  public string setName(name) {
     this.name = name;
  }
}

class DataHandler {
     public DataHandler(da) { // <- Inject an instance of DA
         this.da = da;
     }

     public bool validate() {
          // validation stuff
     }
}

Выглядит нормально, потому что мы не нарушаем указанный SRP. Но здесь у меня есть только один сеттер и только один геттер в классе DA.


Теперь вопросы:

1) Должен ли я всегда создавать еще один класс DA, даже если у меня есть только один сеттер и геттер, просто чтобы он не нарушал SRP?

2) Действительно ли сеттеры и геттеры нарушают SRP и не должны ли они никогда использоваться ни в каком классе?

3) И если да, то всегда ли внедрение зависимостей является ответом!?


comment
:/ вы, вероятно, должны были отредактировать. И если вы нарушаете SRP, вам определенно следует использовать DI. Комбинация над расширением, и все.   -  person    schedule 05.03.2013
comment
Если вы проверите мой предыдущий-предыдущий комментарий (и мой ответ pastebin), вы можете понять, откуда я.   -  person    schedule 05.03.2013
comment
Даже если они не нарушают SRP, они все равно не чистые ИМХО. Проблема заключается в именовании, если у вас есть геттер-сеттер с именем name, у вас больше нет глагола в имени функции. Вы могли бы использовать getSetName, но тогда у него есть два глагола, а крики делают больше, чем одну вещь. Также я думаю, что из-за странного названия это нарушает принцип наименьшего удивления.   -  person Graham Fowles    schedule 09.08.2016


Ответы (1)


Нарушают ли сеттеры и геттеры SRP?

Сеттеры и геттеры не суть. Смысл SRP в том, что у класса должна быть только одна обязанность.

Представление предметной области — большая ответственность. Объект, который делает это, часто называют «объектом данных». Объекты данных обычно имеют сеттеры и геттеры из-за дизайна языка или соглашений, но сами по себе они не являются отдельной обязанностью; они просто сантехника.

Получение объектов данных в постоянном хранилище и из него — еще одна большая ответственность. Объект, который делает это, часто называют «объектом доступа к данным» (DAO). DAO, который также не является объектом данных, вероятно, не нуждается в установках и получателях для атрибутов типа объекта данных, которым он управляет, хотя я могу представить действительно ужасную структуру, которая потребовала бы их. Как и DAO, другие типы объектов, которые выполняют действия с объектами данных (отображают их, сериализуют и десериализуют, выполняют над ними вычисления и т. д.) и сами не являются объектами данных, вероятно, не нуждаются в сеттерах и геттерах, отражающих объекты данных.

Таким образом, наличие сеттеров и геттеров является признаком того, что ваш объект является объектом данных. Если это объект данных, а также DAO или другая большая ответственность, он, вероятно, нарушает SRP.

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

Должен ли я всегда создавать другой класс DA, даже если у меня есть только один сеттер и геттер?

Как правило, да. Дело не в количестве атрибутов; дело в том, что представление и доступ являются двумя разными обязанностями и относятся к разным классам.

Типичные приложения имеют много объектов предметной области, поэтому если вообще имеет смысл отделять объекты предметной области от доступа к ним, имеет смысл делать это последовательно для всех объектов предметной области, даже одноатрибутных.

Всегда ли решение зависит от внедрения зависимостей?

Это зависит от вашей архитектуры и фреймворка. У вас могут быть неизменяемые объекты данных и DAO, чьи методы принимают их в качестве параметров; там нет DI (хотя вы можете внедрить DAO в компоненты более высокого уровня, которые их используют). У вас могут быть DAO, которые создаются с помощью объекта данных или объекта данных, который имеет ссылку на DAO (оба шаблона, которые я видел, но не люблю); вам может понадобиться DI там. В любом случае, это не имеет большого отношения к остальной части обсуждения.

person Dave Schweisguth    schedule 14.02.2016