Задать вопрос
vitaly_74
@vitaly_74

Является ли чтение Readonly свойств объекта нарушением инкапсуляции?

Например в php есть такие свойства объекта как public read only
или например есть такое понятие как DTO
Давайте представим объект и DTO которым пользуется объект. Если объект возаращает DTO как представление самого себя, например методом showStruct(): DTO будет ли это являться нарушением инкапсуляции?

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

С другой стороны я читал что объект должен скрывать свою структуру при хорошей инкапсуляции.
И получился такой замкнутый круг:
Класс который содержит поля - является структурой данных (без поведения). класс который содержит и структуры данных (т.е. свойства) и поведение является объектом.
Класс который содержит структуры данных открытые только для чтения и поведения тоже будет объектом, в полном смысле этого слова. но будет ли нарушена в данном случае инкапсуляция?

И Еще пример. если объект не будет возвращать никаких данных о себе, то тогда как придерживаться принципа OpenClosed? т.е. мы написали объект, спустя время хотим его усовершенствовать основываясь на его предыдущем состоянии (например платежная транзакция, и мы хотим при оплате добавить еще какое-нибудь поведение, поверх стандартного, это можно сделать при помощи декораторов). логично предположить что следуя принципу мы не можем менять старый код. нужно писать новый поверх. но как без знания объекта это сделать? Не будем же мы после каждого требования бизнеса изменять старый код.

Ув. программисты. прошу в своих ответах давать ссылку на статьи которые вы используете, тем самым вы мне очень ьпоможете.
  • Вопрос задан
  • 252 просмотра
Подписаться 2 Простой 14 комментариев
Решения вопроса 1
DollyPapper
@DollyPapper
Вы путаете инкапсуляцию и сокрытие информации. Инкапсуляция это логическое объединение взаимосвязанных логических едениц в одной сущности. Т.е. методы и поля объекта объединяются в одном классе. Это и есть инкапсуляция. А есть такое понятие как сокрытие информации. Это не только про обращение к закрытым полям класса, это вообще про ракскрытие внутренней структуры нашего объекта для внешнего пользователя. Например если мы создаём юзера который в конструкторе принимает id как целое число, это нарушение сокрытия информации, т.к. внешний по отношению к обьекту пользователь знает, что технически внутри наш id это целое число, и например захочет его инкрементировать, а мы не хотим чтобы так было.
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
mayton2019
@mayton2019
Bigdata Engineer
Давайте представим объект и DTO которым пользуется объект. Если объект возаращает DTO как представление самого себя, например методом showStruct(): DTO будет ли это являться нарушением инкапсуляции?

Я понял ваш вопрос. Смотрите. Философия ООП базируется на том что все действия с объектом должны быть санционированы языком или средой выполнения. Например в Java есть техника рефлексии которая позволяет много чего делать например менять приватные поля. Это часто используется в Mock/Mockito и я часто про это говорю. Мокито - фактически взламывает инкапсуляцию. Но это всех устраивает потому-что "тестить нуна!".
В Java также есть технология сериализации-десериализации которая обеспечивает сохранения состояния объектов на диск или передачу их в сеть для дальнейшей работы (например пользовательская сессия прыгает между нодами кластера). И это действие (сериализация) полностью санкционировано средой и языком. Всех это устраивает. Хотя с моей точки зрения - этож капец взлом. Но зато в Java вы никогда не сделаете down-casting объекта одного типа к типу другого если иерархия этого не позволяет. Этого делать нельзя ... ну потому что это точняк нарушение ООП. И нельзя найти никакой санкции на такое странное действие. Вот в языке С++ например вы можете жонглируя указателями взглянуть в любую память своего процесса или потока и прочитать любой байт или word/dword. Что можно сделать в PHP из подобного? Я не знаю. Но новерное что в PHP много механик которые не позволяют делать хакинг когда. Вот. Поэтому ООП и считается философией программирования а вовсе не тюрьмой. Вобщем код надо писать по правилам языка и среды а не "хачить". И лучшие практики ООП они как раз стоят именно на этой идее. Кроме того - не существует единого ООП - а есть просто разные его реализации в разных языках. Короче вы не найдете самого-самого-ООП-шного языка.

А вообще если это опнсорц - ну сделайте себе форк и меняйте что хотите в исходниках.

И Еще пример. если объект не будет возвращать никаких данных о себе, то тогда как придерживаться принципа OpenClosed?

Про что вообще OpenClosed? Это - расширенная трактовка ООП в части SOLID (вторая буква О).
Означает что если вы хотите внести изменение в класс - то вы его наследуете. Например
class BMWX5 extends BMW { .. }
Мы ничего не нарушили. Мы не меняли свойств BMW. Мы создали новый класс BMWX5 где есть изменные методы. Оригинальный BMW мы не трогали. Все - в правовом поле.
Ответ написан
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
dto являются легчайшими объектами взаимодействия с бд, они просто по своей сути не могут содержать в себе логики, вся логика выше
Ответ написан
Комментировать
NikFaraday
@NikFaraday
Student full-stack Developer
Если объект возвращает DTO как представление самого себя

Как? DTO это объект, который просто описывает некую модель данных и не имею поведения (Wikipedia). Ладно, с этим всё равно, едем дальше

нельзя менять свойства объекта из вне, это могут делать только методы объекта

Ну это уже смотря на логику... К примеру, наведу пример из .Net, возьмите стандартный класс от Microsoft по типу Console (Класс для работы с консолью). Там же есть свойства, по типу BackgroundColor, Height, Width и т.д. Изменение размеров окна является нарушением инкапсуляции?

То представление инкапсуляции, что вы имеете, оно опирается только на наличие модификаторов доступа public и private. Является ли инкапсуляцией наличие модификаторов доступа? Нет, потому что не было бы описано 100500 книг и статей по поводу двух модификаторов доступа. Инкапсуляция - это, в первую очередь, целостность объекта, т.е., что объект может взаимодействовать сам с собой через внутренние методы (По типу того, как вы описали).

Но неужели объект не может меняться снаружи, или он не может меняться через публичные свойства? Если бы это было запрещено, то в конвенциях к ООП писалось бы такое ещё и жирным шрифтом, что: "НЕЛЬЗЯ ДЕЛАТЬ СВОЙСТВА ПУБЛИЧНЫМИ".

Для примера, есть такой языка как C++ (Думаю, что вы слышали). Там, в отличии от более продвинутых языков программирования, нет большей части упрощающего функционала (Синтаксического сахара, называйте как хотите). Весь объект строится из полей и методов (С различными комбинациями модификаторов доступа). Есть ли там инкапсуляция? Да. Запрещены ли там публичные поля? Нет.

машина машина должен решать задачи по перевозке водителя,

А если вам скажут настроить взаимодействие двух машин? Да, тут свойства использоваться вряд ли будут, но будет ли нарушение инкапсуляции то, что другая машина будет влиять на первую? Нет. Как они будут это делать? Определённо через методы. Зачем тогда есть публичные свойства и поля?

Класс который содержит поля - является структурой данных (без поведения). класс который содержит и структуры данных (т.е. свойства) и поведение является объектом.

Любой класс является классом. Конкретная реализация описания класс является объектом. Структура данных (Вообще модель данных) является самым простым типом класса. Если у класса есть методы для описания поведения, то он всё равно остаётся объектом некого класса. Как выше написал уже Владимир Коротенко :
dto являются легчайшими объектами взаимодействия с бд, они просто по своей сути не могут содержать в себе логики


мы хотим при оплате добавить еще какое-нибудь поведение, поверх стандартного

Наследование, ещё один принцип ООП. Если полностью закрытый класс даже для наследования (sealed) значит тут уже как не крутись, у вас ничего не получится, как бы вы не ХОТЕЛИ УСОВЕРШЕНСТВОВАТЬ функционал. Значит так задумано вышестоящим разработчиком/ами

но как без знания объекта это сделать

Для этого есть документации. Задумайтесь, на сколько часто вы закрываете свои классы от наследования, когда пишете код?

Не будем же мы после каждого требования бизнеса изменять старый код.

Будете. Будете делать всё что вам скажут, абсолютно.
Ответ написан
php666
@php666
PHP-макака
showStruct(): DTO будет ли это являться нарушением инкапсуляции?
нет.

showStruct() максимум, что может вывести - это свойства объекта скопом, те в массиве. Это все равно, что пройтись по всем его геттерам и получить все свойства объекта DTO. Ибо по определению DTO тупой и пустой как барабан, вся его суть - получить данные откуда-либо, быть заполненным и передать этот DTO в другой слой ПО, который гарантированно получить все необходимые свойства, указанные в объекте.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы