Подтвердить что ты не робот

Законодатель нарушает закон Деметры?

Закон Деметры рассчитывает сделать самую слабую связь между классами.

Это означает, что 90% всех геттеров/сеттеров, экспонирующих в классе, должны быть "удалены" и заменены методом "поведенческий". В самом деле, это соответствует философии "рассказать, не спрашивать", потому что клиент не должен относиться к самому поведению с помощью плохого метода getter/setter. Это уменьшает дублированный код, если одно и то же действие используется в другом месте.

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

С другой стороны, определение шаблона посетителя:

Посетитель позволяет вам определить новую операцию без изменения классов элементов, на которых она работает.

Итак, на первый взгляд, это кажется противоположным ожиданиям Закона Деметры:

  • Один (посетитель) подразумевает структуру класса, чтобы обеспечить getter/setter, чтобы Visitor мог изменять состояния объектов, не касаясь самого класса.

  • Другое (Деметра) поощряет заключать все поведенческие коды, непосредственно связанные с объектом в одном классе.

Итак, мой вопрос:

Когда мы можем считать, что класс закрыт для модификации и, таким образом, перестает добавлять к нему поведенческие методы и поэтому предпочитает добавлять их во вновь создаваемом посетителе с большим риском того, что клиент использует геттеры/сеттеры вместо методов поведения, которые уже были выставлены раньше в начальном классе?

4b9b3361

Ответ 1

Короткий ответ нет.

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

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

По другому вопросу я немного запутался в вашем последнем абзаце, так как не знаю, говоришь ли ты об открытом/закрытом принципе или о том, как создать функцию с использованием шаблона посетителя.

Одна заметка, я думаю, что ключ должен понять, что SOLID, Закон Деметры и все другие практики - это лучшие практики, а не лучшие практики ( "лучшие практики" является маркетинговым термином). Если вы примете любую из этих практик до крайности, они, вероятно, окажут вред читабельности или поддерживаемости кода.

(кстати, хороший вопрос: D)


Преимущество открытого/закрытого принципа в основном относится к коду, который будет использоваться другими людьми способами, которые мы не можем предвидеть (в качестве примера можно привести рамки). Поэтому, если вы пишете фреймворк, вам нужно будет добавить точки добавочного номера и использовать функцию языка, чтобы предотвратить наследование класса (например, final в java или запечатанном на С#) или просто позволить разработчику переопределить определенные методы. Идея состоит в том, чтобы предотвратить наивное пользователя от переопределения важной части объекта и непредвиденным образом разорвать инфраструктуру. Некоторые языки/структуры смеются над этим (например, Ruby/Rails), и они поощряют пользователей открывать классы для добавления или изменения функций (с некоторым успехом).

Если вы пишете приложение (и вы владеете кодом), я бы предложил вам не уделять слишком много внимания принципу открытого/закрытого языка и сосредоточиться на применении Закона Деметры (в разумной степени: D).