34 / 34 / 37
Регистрация: 21.06.2012
Сообщений: 152
|
||||||
1 | ||||||
Нарушение инкапсуляции или нет?16.07.2017, 23:51. Показов 3941. Ответов 24
Метки нет (Все метки)
В общем экспериментируя с крестами сделал такую штуку и не могу понять это нарушение инкапсуляции или нет?
1
|
16.07.2017, 23:51 | |
Ответы с готовыми решениями:
24
Нарушение инкапсуляции или нет? Нарушение инкапсуляции метода Нарушение авторского права или нет? Нарушение закона обавторском праве или нет? |
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
17.07.2017, 22:15 | 21 |
h3mbr0,
Интересный пример, но минусов там много Опишу основные; 1) Казалось бы мы хотели дать доступ только к методу установки имени, а в итоге дали доступ ко всем протектедам и прайветам. В итоге остаётся возможность изменить те поля которые не предназначены для модификации извне. Да, можно надеяться на то что все кто будут работать с этим кодом будут внимательны и сообразят не прибегать к иным ухищрениям, но с таким же успехом тот самый метод можно сделать public и так же положиться на внимательность программистов и полагать, что метод setName класса Child будет вызываться только из класса Mother. 2) Вызовы разрешённые только в определённых контекстах как в том примере, создают путаницу особенно если проект большой и таких вызовов много. Глядя на такой код нельзя сходу определить чего именно можно вызывать дружественному классу а чего нет. Без friend же достаточно взглянуть на внешний интерфейс и все, никаких заморочек. 3) Такой дизайн насколько я помню нельзя описать при помощи таких штучек UML 4) Смысл приватных и защищённых членов немного в другом. Они нужны что бы скрыть детали реализации, и иметь возможность разработчику этих деталей манипулировать ими по нужде, отражая изменения для вызывающей стороны без изменения внешнего интерфейса - это и есть основное назначение всех этих модификаторов (протектед, прайвет). По поводу примера: Я имел ввиду, если вы читаете приватное поле иного класса (особенно в нескольких местах), то если завтра вам понадобится читаемое число например умножить на два, то: 1) если вы сами являетесь автором кода, то вам придётся во всех вызовах сделать это умножение 2) хуже того, если вы пользуетесь такой библиотекой, и её автору нужно умножить это число на два, то тут по понятным причинам ситуация становится ещё более сложнее. Умножение на два это был простой пример. На практике как правило все гораздо сложнее. Вот почему детали не должны нас волновать. Когда человек садится за руль ему все равно чего там у него сейчас под капотом, его не интересуют эти детали, которые производитель может заменить в любое время. Все что интересно водителю это наружний интерфейс, тобишь крутить педали...
0
|
rikimaru2013
|
17.07.2017, 22:16
#22
|
Не по теме: 5 часов сидел, обновлял страницу - ждал драки с hoggy - а он не пришёл(((( А с Nosey по 9 страниц холиварят ((((
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||
17.07.2017, 22:38 | 23 | |||||
что такое вообще "инкапсуляция" ?
это - языковый механизм, который позволяет оградить и защитить данные от внешнего вмешательства. иными словами, детали внутренней реализации не зависят от внешней стороны. а внешняя сторона не зависит от деталей реализации. киллер-фича инкапсуляции заключается в том, что мы можем менять детали реализации не боясь поломать код вызывающей стороны. и наоборот: детали реализации не зависят от изменений в коде вызывающей стороны. в данном случае, класс Bar впадает в зависимость от деталей реализации класса Foo. мало того, что класс Foo теряет контроль за целостностью собственных данных (нарушение инварианта - зависимость корректности собственной работоспособности от корректности вызывающей стороны), так ещё кроме прочего - между классами возникает легаси. мы уже не можем менять детали реализации этих классов, без оглядки друг на друга. существуют кейсы, когда классы-друзья - естественные части общего дизайна. и это не является нарушением инкапсуляции. например - итераторы контейнеров:
вынесенная в отдельный класс здесь нет нарушения инкапсуляции, поскольку контейнер и его итератор - один неделимый механизм, разнесенный по двум разным классам. конечно они зависят друг от друга. но это точно такая же зависимость, как зависимость отдельных частей реализации друг от дружки. ----------------------------------------- кто то из именитых авторов писал: "старайтесь до последнего не возвращать из класса указатели/ссылки на внутренние данные. вернули указатель на внутренний буфер - считай слили весь инвариант класса. ведь теперь класс уже не может гарантировать целостность буфера, и зависит от корректности вызывающей стороны". тезис не лишен логики, но слегка отдает паранойей. действительно, заполучив снаружи указатель на данные, мы можем например забить их по delete, а класс потом крашнется когда нибудь потом. однако ж возвращать все данные по значению может оказаться неоправданно дорогостоящим, и мы можем вернуть какую нибудь константную ссылку на строку, в расчете, что программист-пользователь не и не прибегать к расточительному копированию. однако, посмотрите что в данном случае сливает наружу Bar? я не знаю, для чего такое вообще может понадоибиться, однако, он сливает вообще любому желающему поле стороннего класса, причем, в таком кейсе, которое предполагает прямое вмешательство в чужие данные. с таким же успехом можно было бы сразу сделать поле открытым в классе foo Добавлено через 15 секунд
5
|
298 / 107 / 31
Регистрация: 12.03.2012
Сообщений: 449
|
|
17.07.2017, 22:43 | 24 |
Поскольку чтобы добавить friend class нужно модифицировать код класса, никакие ухищрения тут не работают, а добавлять friend самому - все равно что менять доступ ко всем полям на public
Если ты вмешался в код класса, то это уже другое дело, но пока все сокрыто за private и protected, а дружественный класс реализуется тем же разработчиком, для того, кто эти классы использует нет возможности получить доступ к "лишнему", для них все по-прежнему инкапсулировано Глядя на большой проект обычно ничего сходу определить нельзя Вы об этом? 4 пример я не очень понял, уж извините А в том то и дело, что по задумке детали остаются под капотом. В данном случае я бы рассматривал дружественные классы как единую единицу ООП, и все бы встало на свои места Добавлено через 3 минуты Лично я всегда рассматривал только такую ситуацию, и не вполне понял как может быть иначе...
0
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
17.07.2017, 23:36 | 25 |
h3mbr0,
Так о том и речь что все что нужно и не нужно для друга становится пабликом Данные которые не должны волновать друга и не должны быть никому видны, почему то торчат наружу(это и есть открытая возможность для ухищрений). Вот если бы была возможность конкретизировать чего именно можно видеть другу а чего нет, тогда ваш пример можно было бы вытянуть А так если рассуждать по всем канонам, лучше обойтись иным подходом... По поводу больших проектов - чем меньше путаницы, тем проще. Ок возьмём всего два класса. Вот смотрю я в большой класс другом которого тоже является большой класс, и куча защищённых полей и методов. Иди теперь разбери чего другу можно вызывать а чего нет и не наломай дров, особенно если приходится допиливать чужой код в этом духе. Пожалуй это один из немногих случаев, когда без друзей проще жить Все что можно юзать это паблики и ни у кого голова не болит. Насчёт UML похоже я не зря сомневался Вроде все есть для описания друзей. Да, можно рассматривать дружественные классы как одно целое, но до поры до времени. Сори, нормально квотировать не удаётся, пишу с мобилы
0
|
17.07.2017, 23:36 | |
17.07.2017, 23:36 | |
Помогаю со студенческими работами здесь
25
Можно ли по названию платы,или по чипу,или по соккету,определить,поддерживает плата ХР или нет? Ошибка с массивами, хотя формально её нет (похожи ли массивы или нет?) Нет звука или нет звуковой карты Вывести на экран слова, в которых все символы повторяющиеся, или сообщение «Нет», если требуемых слов нет Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |