OberonCore https://forum.oberoncore.ru/ |
|
ABSTRACT RECORD versus EXTENSIBLE RECORD? https://forum.oberoncore.ru/viewtopic.php?f=23&t=6587 |
Страница 1 из 1 |
Автор: | adimetrius [ Пятница, 20 Март, 2020 12:12 ] |
Заголовок сообщения: | ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Коллеги, выскажитесь, пож, чем руководствоваться при выборе ABSTRACT RECORD versus EXTENSIBLE RECORD? Поясню. В ББ есть абстрактные типы (TextViews.View), и стандартная реализация полностью отделена от абстрактного интерфейса. Есть также "полуабстрактные" типы (Containers.View), которые часть функциональности реализуют в своем модуле, а часть - оставляют для реализации производными. А вот у меня задача, где я полностью могу реализовать функциональность и тип данных. Причем это не "стандартная" реализация, а всеобщая реализация: т.е. "так должно быть всегда и для всех". Но при этом нужно предусмотреть возможность расширения, чтобы клиенты могли дополнять своими данными и, возможно, своим поведением (о котором мне не нужно ничего знать). Я бы сделал так: Код: TYPE Type* = POINTER TO EXTENSIBLE RECORD x*, y-, z: ... END; PROCEDURE (t: Type) P*, NEW, EXTENSIBLE; (* производные ДОЛЖНЫ вызывать P^ *) Ну или так, чтобы не полагаться на ^ супервызовы: Код: PROCEDURE (t: Type) P2*, NEW, EMPTY; PROCEDURE P* (t: Type); (* или PROCEDURE (t: Type) P*, NEW; *) BEGIN ...; t.P2 END P; Или все-таки стоит сделать Код: TYPE Type* = POINTER TO ABSTRACT RECORD x*, y-, z: ... END; StdType = POINTER TO RECORD(Type) ... END; Какими руководствоваться критериями при выборе? |
Автор: | Александр Ильин [ Пятница, 20 Март, 2020 19:59 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Основное различие состоит в том, что клиент не может создавать экземпляры абстрактного типа с помощью процеруры NEW. Соответственно, смотрите сами, имеет ли смысл их создавать. Если внутри или вокруг базового типа уже есть некий функционал, который позволяет его создать и осмысленно использовать, пусть этот базовый тип будет EXTENSIBLE. Если вы хотите запретить клиентам создавать экземпляры и хотите, например, чтобы всё создавание происходило внутри вашего модуля (для установки и поддержания каких-то инвариантов времени исполнения), то публикуйте только ABSTRACT тип, а конкретные расширения делайте непубличными. В последнем случае клиент тоже сможет создать свои расширения и передать вам в обход установки инвариантов, но ваши функции смогут их легко идентифицировать проверкой типа и пресечь их работу (трапнуть на предусловии, например). |
Автор: | Info21 [ Пятница, 20 Март, 2020 21:42 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Насколько я понимаю, EXTENSIBLE надо избегать. Если нужно предложить дефолтные методы с возможностью их переопределения, то лучше предложить простые процедуры, реализующие соответствующую функциональность, а методы оставить абстрактными. |
Автор: | adimetrius [ Пятница, 20 Март, 2020 21:58 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Info21 писал(а): Насколько я понимаю, EXTENSIBLE надо избегать. Я собсно этого и придерживаюсь обычно. Но вот не помню, почему )). Видимо, оч давно придерживаюсь Почему же надо избегать EXTENSIBLE? |
Автор: | adimetrius [ Пятница, 20 Март, 2020 22:01 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Александр Ильин писал(а): Если внутри или вокруг базового типа уже есть некий функционал, который позволяет его создать и осмысленно использовать, пусть этот базовый тип будет EXTENSIBLE. О, вот это мне понятно, вполне как критерий звучит. Если я прально понял, можно уточнить "...осмысленно использовать без расширения,... |
Автор: | Дмитрий Дагаев [ Суббота, 21 Март, 2020 09:48 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
В Вашем случае (EXTENSIBLE RECORD с наличием EXTENSIBLE методов) нужно избегать потенциальных проблем наследования реализации (хрупкий базовый класс и проч). Применение ABSTRACT эти проблемы снимает. Но ABSTRACT добавляют проблему повторного использования кода, когда в каждом производном объекте приходится частично дублировать код реализации. Что приводит к необходимости рефакторинга. Для повторного использования кода лучше применять методы с измененными именами, а не EXTENSIBLE. Но есть ситуация, когда EXTENSIBLE вполне допустимо - когда Вы с этими проблемами управляетесь в одном модуле Module2: ABSTRACT Module1.Rec -> EXTENSIBLE Module2.Rec -> Module2.RecSpec1, Module2.SpecRec2, .. При этом Вы должны выводить наружу только Module1.Rec |
Автор: | Илья Ермаков [ Суббота, 21 Март, 2020 10:43 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Коллеги выше уже разъяснили основное. Но если речь не о типе "пассивной" записи, без поведения, то чаще всего лучше объявлять EXTENSIBLE (как и было в классическом Обероне). Проблемы хрупкости нет, а возможность расширить сообщение или какой-то параметризующий параметр остаётся. В отношении классов: - если проектируете что-то широкого применения, то лучше только ABSTRACT (не закладывать хрупкость, пусть и ценой уменьшения повторного использования). - если речь о структуре в конкретно вашем приложении (не в переиспользуемом компоненте), то при явной целесообразности можно и EXTENSIBLE, не надо совсем жёсткой догматики. Есть случаи, когда EXTENSIBLE и разрешение переопределять методы целесообразны и не связаны с хрупкостью, но это отдельные случаи. |
Автор: | Александр Ильин [ Суббота, 21 Март, 2020 14:30 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
adimetrius писал(а): Александр Ильин писал(а): Если внутри или вокруг базового типа уже есть некий функционал, который позволяет его создать и осмысленно использовать, пусть этот базовый тип будет EXTENSIBLE. О, вот это мне понятно, вполне как критерий звучит. Если я прально понял, можно уточнить "...осмысленно использовать без расширения,... |
Автор: | Илья Ермаков [ Суббота, 21 Март, 2020 16:36 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Да, хорошо сформулировал Александр. |
Автор: | Info21 [ Воскресенье, 22 Март, 2020 00:10 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Дмитрий Дагаев писал(а): Но ABSTRACT добавляют проблему повторного использования кода, когда в каждом производном объекте приходится частично дублировать код реализации. Что приводит к необходимости рефакторинга. Непонятно.
|
Автор: | Дмитрий Дагаев [ Воскресенье, 22 Март, 2020 09:33 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Info21 писал(а): Дмитрий Дагаев писал(а): Но ABSTRACT добавляют проблему повторного использования кода, когда в каждом производном объекте приходится частично дублировать код реализации. Что приводит к необходимости рефакторинга. Непонятно.Рассмотрим пример Files.File - ABSTRACT тип, который требует реализации. 1. Есть реализация для Windows - HostFiles.File. 2. Есть реализация для Linux - тот же HostFiles.File. Как она сделана? Скопирована реализация для Windows, а потом платформо-зависимый код, отмеченный цветом, изменен А.Ширяевым и др. для Linux. Но остальной код реализации - дублируется, а такого кода очень много. С дублированием кода в ООП (Фаулер) предлагается бороться рефакторингом. Скажем, возможно было бы создавать (в HostFiles или где-то еще) EXTENSIBLE File реализацию, складывать туда дублируемый код, а платформо-зависимое сводить (в HostFiles) LinFile = RECORD (File)... END. |
Автор: | Comdiv [ Воскресенье, 22 Март, 2020 12:39 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Дмитрий Дагаев писал(а): С дублированием кода в ООП (Фаулер) предлагается бороться рефакторингом. Скажем, возможно было бы создавать (в HostFiles или где-то еще) EXTENSIBLE File реализацию, складывать туда дублируемый код, а платформо-зависимое сводить (в HostFiles) LinFile = RECORD (File)... END. Это можно решить иначе. Files.File может быть даже нерасширяемым типом, который содержит только платформо-неспецифический код, который вызывает, содержащийся в нём экземпляр полностью абстрактного типа, который, в идеале, содержит только минимально необходимый платформо-специфический код. Я стараюсь всегда пользоваться такой схемой, когда нет зависимости от сторонних библиотек. Хорошо тем, что есть чёткое разделение на переопределяемые вещи и постоянные, требуется минимальное количество понятий в языке и повышается уровень динамичности в конструировании. Недостаток - может потребоваться больше памяти на композицию и, в целом, может вырасти уровень косвенности. |
Автор: | Илья Ермаков [ Воскресенье, 22 Март, 2020 12:58 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Comdiv писал(а): Это можно решить иначе. Files.File может быть даже нерасширяемым типом, который содержит только платформо-неспецифический код, который вызывает, содержащийся в нём экземпляр полностью абстрактного типа, который, в идеале, содержит только минимально необходимый платформо-специфический код. У плюсистов - идиома PIMPL, если не ошибаюсь? (pointer to implementation)? |
Автор: | Дмитрий Дагаев [ Воскресенье, 22 Март, 2020 14:09 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Comdiv писал(а): Дмитрий Дагаев писал(а): С дублированием кода в ООП (Фаулер) предлагается бороться рефакторингом. Скажем, возможно было бы создавать (в HostFiles или где-то еще) EXTENSIBLE File реализацию, складывать туда дублируемый код, а платформо-зависимое сводить (в HostFiles) LinFile = RECORD (File)... END. Это можно решить иначе. Files.File может быть даже нерасширяемым типом, который содержит только платформо-неспецифический код, который вызывает, содержащийся в нём экземпляр полностью абстрактного типа, который, в идеале, содержит только минимально необходимый платформо-специфический код. Я стараюсь всегда пользоваться такой схемой, когда нет зависимости от сторонних библиотек. Хорошо тем, что есть чёткое разделение на переопределяемые вещи и постоянные, требуется минимальное количество понятий в языке и повышается уровень динамичности в конструировании. Недостаток - может потребоваться больше памяти на композицию и, в целом, может вырасти уровень косвенности. Все Вы правильно говорите. Но я и не утверждал, что EXTENSIBLE - единственное правильное решение. Более того, я говорил, что Дмитрий Дагаев писал(а): Для повторного использования кода лучше применять методы с измененными именами, а не EXTENSIBLE. Но есть ситуация, когда EXTENSIBLE вполне допустимо Но, поскольку в данной теме речь шла о случаях, когда допустимо использовать EXTENSIBLE, я привожу пример такого использования, чтобы исключить дублирование кода. |
Автор: | adimetrius [ Воскресенье, 22 Март, 2020 16:27 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Comdiv писал(а): Дмитрий Дагаев писал(а): С дублированием кода в ООП (Фаулер) предлагается бороться рефакторингом. Скажем, возможно было бы создавать (в HostFiles или где-то еще) EXTENSIBLE File реализацию, складывать туда дублируемый код, а платформо-зависимое сводить (в HostFiles) LinFile = RECORD (File)... END. Это можно решить иначе. Files.File может быть даже нерасширяемым типом, который содержит только платформо-неспецифический код, который вызывает, содержащийся в нём экземпляр полностью абстрактного типа, который, в идеале, содержит только минимально необходимый платформо-специфический код. Я применил такую схему для модуля Windows, когда делал Тайлер (плиточный интерфейс). Там, как Д.В. написал: в Windows был только интерфейс, вся реализация в HostWindows, и она совмещала платформо-зависимые и независимые части. Например, к платформо-независимым относится понятие Front и Target окна - это не зависит от Лин-Вин. Я интуитивно отделил платформо-независимые части и "поднял" их в Windows и, в основном, сделал свободными процедурами, поскольку переопределение или расширение не предусматривается. А для всего платформо-зависимого выделил новый тип WindowBackend, который в Windows только абстрактный интерфейс, а вся реализация в HostWindows. Модуль HostWindows существенно упростился, сократился в 2 раза - легче будет переносить под другие платформы. Но в этой теме про критерии. И вот вопрос: критерий хорош, предложенный Александром; однако если руководствоваться только им, то TextModels.StdModel вполне можно экспортировать и позволять расширять. Значит надо формальный критерий как-то уточнять или дополнять. |
Автор: | Info21 [ Воскресенье, 22 Март, 2020 18:18 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Общие куски в HostFiles должны быть реализованы как простые процедуры в Files. Реализация в HostFiles их использует, и реализация в Linux тоже. Архитектура ББ в этом смысле недоработана. Но всё заранее угадать нельзя, поэтому и случается копипаста. Но это не аргумент для затычек вроде EXTENSIBLE. |
Автор: | Дмитрий Дагаев [ Воскресенье, 22 Март, 2020 18:45 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Info21 писал(а): Общие куски в HostFiles должны быть реализованы как простые процедуры в Files. Реализация в HostFiles их использует, и реализация в Linux тоже. Архитектура ББ в этом смысле недоработана. Но всё заранее угадать нельзя, поэтому и случается копипаста. Но это не аргумент для затычек вроде EXTENSIBLE. Это - действительно не аргумент. Это - ответ на Ваш вопрос: прояснить, что ABSTRACT добавляет проблему повторного использования кода. Я прояснил на примере HostFiles - проблема есть, и дело не в том, что кто-то там не угадал. А аргумент был такой Цитата: Но есть ситуация, когда EXTENSIBLE вполне допустимо - когда Вы с этими проблемами управляетесь в одном модуле Module2: ABSTRACT Module1.Rec -> EXTENSIBLE Module2.Rec -> Module2.RecSpec1, Module2.SpecRec2 Скажу другими словами, что если Вы наследуете от одного абстрактного типа 10 специфических (и еще 20 в уме), то вставка между ними EXTENSIBLE в том же модуле будет оправдана. Ну там, графические объекты Rect, Oval, Circle, Text, Poly... А потом появляются типы Text3D, Rect3D. Один человек будет править этот модуль, проблемы хрупкого базового класса не возникнет. Является ли EXTENSIBLE единственным возможным решением в этом случае? Нет. |
Автор: | Info21 [ Понедельник, 23 Март, 2020 10:26 ] |
Заголовок сообщения: | Re: ABSTRACT RECORD versus EXTENSIBLE RECORD? |
Не согласен, что добавляет именно ABSTRACT, -- или не понял аргумента. Оставить EXTENSIBLE для использования внутри модуля, запретив экспорт типов с этим атрибутом, -- лучше, чем оставлять как есть, но сложнее, чем вовсе убрать. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |