DollyPapper
@DollyPapper

Нарушают ли конструкторы инкапсуляцию?

Добрый день. Вопрос собственно такой. При передаче первоначальных параметров классу, мы обычно сохраняем эти значения в его свойствах. То есть по сути конструктор является таким своеобразным сеттером для полей класса. По моему это явное нарушение инкапсуляции. Или нет? Ведь сеттеры ругают именно за то, что мы можем на прямую изменить поля обьекта, вмешиваясь в его структуру из вне. Но в конструкторе мы же делаем тоже самое. Да, после создания обьекта при отсутствии сеттеров мы уже на прямую не можем изменить поля, но единожды при создании это происходит, и мы раскрываем внутреннее устройство нашего обьекта. Где проходит эта самая черта, где инкапсуляция нарушается, а где нет. Вопрос скорее из разряда философии, но интересно кто что думает.
  • Вопрос задан
  • 197 просмотров
Решения вопроса 2
greabock
@greabock
Могу
1. Сеттеры не нарушают инкапсуляцию.
Если вы устанавливаете свойство через сеттер, вы вообще уверены, что оно хранится в свойстве с тем же именем того же класса?
object.setProperty(value)

Вот я, глядя снаружи вообще хз, где и как хранится это свойство, если вообще хранится. А вы?

2. Конструктор не нарушает инкапсуляцию. Ровно по тем же причинам.

По понятным причинам, у вас не на всё должны быть сеттеры, а только те, что вы хотите менять снаружи. Если же у вас сеттеры, на все подряд свойства, то это вы нарушаете инкапсуляцию. Сеттеры тут не при чем.
Ответ написан
gscraft
@gscraft
Программист, философ
Это почему сеттеры нарушают инкапсуляцию? Вовсе нет. Контроль сохраняется за внутренней логикой класса. И в отношении конструкторов, получается, странным образом интерпретируете инкапсуляцию. Логика ООП практически потеряет смысл, если нельзя будет настраивать поведение объектов. Каким образом с чем-либо взаимодействовать, если нет значений, которые можно передать объекту?

Самая банальная проблема, которую решает инкапсуляция, это нарушение работы объекта и непредсказуемость последствий при прямом обращении к свойствам объекта. Например, у нас есть класс, реализующий работу с файлом, и одним из его свойств является дескриптор открытого файла. Если открыть файл, а затем обнулить или заменить дескриптор, то объект потеряет контроль над открытым ранее файлом. Понятно, что это свойство должно быть целиком закрыто и лишено внешнего доступа. Но объект может инициализироваться с путем файла, и путь к файлу может быть так же сеттером, и при изменении пути файла пользователем можно корректно среагировать, от исключения до закрытия ранее открытого файла. Это двоякое свойство, которое логично сохранить, скажем, только для конструктора — объекту необходимо установить это свойство, и объект прямо ассоциируется с путем, ему переданным, цикл жизни будет связан с конкретным файлом. Могут быть и иные опции, например, размер буфера, который можно позволить менять в реальном времени, перенастраивая некоторые параметры работы с файлом в логике сеттера и т.д..

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
19 сент. 2021, в 02:12
800 руб./в час
18 сент. 2021, в 23:51
800 руб./в час
18 сент. 2021, в 23:22
3000 руб./за проект