OberonCore https://forum.oberoncore.ru/ |
|
Супер-вызовы https://forum.oberoncore.ru/viewtopic.php?f=29&t=614 |
Страница 1 из 1 |
Автор: | Калям [ Четверг, 16 Август, 2007 17:22 ] |
Заголовок сообщения: | Супер-вызовы |
В "Сообщении о языке" утверждается, что супер-вызовы - средство устаревшее, а следовательно нужно стараться не использовать его. Однако в том же "Сообщении" есть пример, где используется именно супер-вызов (глава 10.2 Методы). Также, насколько помню, на форуме даже говорили, что они сплошь и рядом в самОй реализации BB. Кто может объяснить такое положение? Теперь о конкретной проблеме, которую ставит отказ от супер-вызовов: как предлагается обходиться без них? Вот пример: есть связанная переопределяемая процедура (метод), код которой - 1000 строк. В некотором потомке потребовалось переопределить её, причём добавляемая функциональность мала, скажем 50 строк кода. Если не использовать супер-вызов, то, фактически, придётся заново реализовывать те же самые 1000 строк в этой переопределённой процедуре (+50 новых), что, согласитесь, нерационально. Как предлагается поступать? |
Автор: | Илья Ермаков [ Четверг, 16 Август, 2007 19:15 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Супервызовов в исходниках среды довольно немного. Точно так же, как относительно немного и наследования реализации - только в заготовках Framework, и то - типы с реализацией всё равно сделаны абстрактными. Проблема наследования реализации много раз обсуждалась - в компонентном ПО возникают проблемы: хрупкого базового класса и т.п., это описано у Пфистера в "Компонентом ПО". В системном программировании следует избегать использования наследования реализации, использовать только гомогенные иерархии наследования (абстрактный тип-интерфейс - конкретное расширение-реализация, неэкспортируемое). И так не только в КП, такой подход является основой многих ООП-паттернов (в частности, рекомендуется в книге Гаммы и др. "Паттерны объектно-ориентированного проектирования", построенной на Smalltalk и С++, живым примером которой является, тем не менее, BlackBox). По поводу "переписываний кода" - это решается другими связями между классами, например, делегированием вызова или композицией. Не следует делать "жирные" классы, а всегда разбивать на небольшие, несущие небольшую ответственность. Затем эти небольшие классы комбинируются, давая нужную конструкцию. При этом друг с другом они взаимодействуют только через абстрактные интерфейсы. Это позволяет в любой момент заменить один из классов в конструкции на другой с таким же интерфейсом. Примеры таких решений - паттерны Model-View-Controller, фирменно-блэкбоксовый Carrier-Rider-Mapper. А в подсистеме Text вообще выделено больше типов, чем модель-отображение-диспетчер: ещё и Mappers, Setters - отвечающий за вёрстку на странице, Rulers... Всегда достаточно переписать только один из этих типов, да и то не обязательно целиком - можно просто обернуть стандартную реализацию, заменяя некоторые вызовы, а остальные делегируя обёрнутому объекту... |
Автор: | Илья Ермаков [ Четверг, 16 Август, 2007 19:30 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Однако если всё-таки используется наследование реализации... Например, если пишется "каркас-заготовка", или решается прикладная задача, где иерархии идут от самой предметной области... То супервызовы всё равно не нужны, вместо них лучше использовать "версионированные методы". Пример в ББ - тип Containers.Container. Возьмём его процедуру HandleCtrlMsg. Она имеет реализацию. Более того, она предназначена для расширения в потомках. Однако - она не EXTENSIBLE! Как так? Очень просто. Container имеет другую процедуру - HandleCtrlMsg2, объявленную как EMPTY (т.е. пустышку) и с экспортом "-" - т.е. только для реализации. HandleCtrlMsg в нужном месте вызывает HandleCtrlMsg2. В итоге - в типах-расширениях мы определяем HandleCtrlMsg2. Супервызова не используем - вызывать нечего... Наоборот, базовая процедура вызывает нас, в тот момент, когда считает нужным. Защита от ошибок - во-первых, вызвать HanleCtrlMsg2 напрямую никто не может, т.к. она экспортирована только для реализации (хе-хе, ни в одном другом языке такого нет ![]() В то же время мы, определяя в своих типах дополнительные действия, не можем умышленно или намеренно забыть или вызвать не вовремя базовую процедуру. Т.е. как именно и когда что выполнять, решает базовый тип, а не расширения. |
Автор: | Wlad [ Четверг, 16 Август, 2007 22:01 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Калям писал(а): есть связанная переопределяемая процедура (метод), код которой - 1000 строк. Ой! Вы меня испугали! :о) Это что-то - из ряда-вон - больше трёх экранов на процедуру! |
Автор: | Калям [ Четверг, 16 Август, 2007 22:15 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Владимир Лось писал(а): Это что-то - из ряда-вон - больше трёх экранов на процедуру! Пример гипотетический. |
Автор: | Wlad [ Четверг, 16 Август, 2007 22:46 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Калям писал(а): Владимир Лось писал(а): Это что-то - из ряда-вон - больше трёх экранов на процедуру! Пример гипотетический. Гипотетически автор закладывается на расширение при проектировании (примерно, как скзал Илья и как позволяет язык). Иначе он - сам себе злобный Буратино! |
Автор: | Сергей Губанов [ Пятница, 17 Август, 2007 13:25 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Илья Ермаков писал(а): ...(хе-хе, ни в одном другом языке такого нет ![]() В C# есть комбинация модификаторов protected internal - Access is limited to the current assembly or types derived from the containing class. Это примерно тоже что и экспорт только для реализации Component Pascal. |
Автор: | Александр Ильин [ Пятница, 17 Август, 2007 16:14 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Сергей Губанов писал(а): Access is limited to the current assembly or types derived from the containing class. А derived class может этот метод вызывать? В BlackBox не может. |
Автор: | Сергей Губанов [ Пятница, 17 Август, 2007 16:40 ] |
Заголовок сообщения: | Re: Супер-вызовы |
Александр Ильин писал(а): Сергей Губанов писал(а): Access is limited to the current assembly or types derived from the containing class. А derived class может этот метод вызывать? В BlackBox не может. Ну, может, но вызываемый код описан в нём же - от самого себя что ли защищать-то? Вобщем, несмотря на тонкие различия, protected internal решает ровно ту же задачу что и экспорт только для реализации. |
Автор: | Илья Ермаков [ Пятница, 17 Август, 2007 18:43 ] |
Заголовок сообщения: | Re: Супер-вызовы |
И угадайте с трёх раз, кто принёс "факел знаний" о безопасных режимах ООП в компонентном программировании в Микрософт.. ![]() |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |