Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
|
bb:extendnohost [2016/04/06 20:31] prospero78 [Герметизация абстракции локатора внутри компонента] |
bb:extendnohost [2016/04/06 20:34] prospero78 [Пример использования] |
Возможность выделения конкретной реализации хост-компонента в общеупотребимую подсистему/компонент ведет к еще одной проблеме - разрастание интерфейса базового класса хост-компонента. Так как существует бесчисленное количество ситуаций применения, возможны ситуации, когда существующих возможностей станет недостаточно, и разработчики будут вносить все новые методы и функции, что вызовет несовместимость различных версий реализации и проблему хрупкости базового класса. | Возможность выделения конкретной реализации хост-компонента в общеупотребимую подсистему/компонент ведет к еще одной проблеме - разрастание интерфейса базового класса хост-компонента. Так как существует бесчисленное количество ситуаций применения, возможны ситуации, когда существующих возможностей станет недостаточно, и разработчики будут вносить все новые методы и функции, что вызовет несовместимость различных версий реализации и проблему хрупкости базового класса. |
==== Использование возможностей расширения абстракции ==== | ==== Использование возможностей расширения абстракции ==== |
Учитывая проблему возможного раздувания интерфейса, а так же тот факт, что единственным способом расширения интерфейса локатора является наследование, предлагается выполнить отвязку доступных функций локатора от интерфейса базового класса. Используем возможности шаблона "Объект-сообщение" для обеспечения параметрического полиморфизма методов локатора (в рамках языка Компонентный Паскаль полиморфизм реализуется данным образом). | Учитывая проблему возможного раздувания интерфейса, а так же тот факт, что единственным способом расширения интерфейса локатора является наследование, предлагается выполнить отвязку доступных функций локатора от интерфейса базового класса. Используем возможности шаблона "Объект-сообщение" для обеспечения параметрического полиморфизма методов локатора (в рамках языка **Компонентный Паскаль** полиморфизм реализуется данным образом). |
Для этого опишем класс-наследник локатора: ''OberFiles.Locator'', в интерфейс которого добавим метод ''.HandleMsg(VAR msg: ANYREC)''. Реализацию этого локатора разместим в модуле ''OberHostFiles.Locator''. В данной реализации мы используем возможности модуля HostFiles, для простоты. При этом, понятно, что реализация локатора с хэндлером может быть размещена сразу в реализации файловой подсистемы BlackBox, так как ''OberFiles.Locator'' по-прежнему является абстрактным типом. | Для этого опишем класс-наследник локатора: ''OberFiles.Locator'', в интерфейс которого добавим метод ''.HandleMsg(VAR msg: ANYREC)''. Реализацию этого локатора разместим в модуле ''OberHostFiles.Locator''. В данной реализации мы используем возможности модуля ''HostFiles'', для простоты. При этом, понятно, что реализация локатора с хэндлером может быть размещена сразу в реализации файловой подсистемы **BlackBox**, так как ''OberFiles.Locator'' по-прежнему является абстрактным типом. |
Важной частью системы является механизм автоматического приведения типа ''Files.Locator'' к типу ''HostFiles.Locator'', при этом фактический результат операции приведения может содержать объект-обертку, так как с различными реализациями локатора могут быть связаны различные модули-реализации ''OberFiles.Locator'' (например, HostFiles <- OberHostFiles). | Важной частью системы является механизм автоматического приведения типа ''Files.Locator'' к типу ''HostFiles.Locator'', при этом фактический результат операции приведения может содержать объект-обертку, так как с различными реализациями локатора могут быть связаны различные модули-реализации ''OberFiles.Locator'' (например, HostFiles <- OberHostFiles). |
<code> | <code oberon2> |
PROCEDURE GuardLoc*(loc: Files.Locator): Locator; | PROCEDURE GuardLoc*(loc: Files.Locator): Locator; |
VAR ret: Locator; | VAR ret: Locator; |
END GuardLoc; | END GuardLoc; |
</code> | </code> |
Опираясь на базовый тип ANYREC мы описываем протокол (набор типов сообщений) взаимодействия с локатором, при этом, сам локатор не зависит от этих протоколов, они обрабатываются только в реализации OberHostFiles. | Опираясь на базовый тип ''ANYREC'' мы описываем протокол (набор типов сообщений) взаимодействия с локатором, при этом, сам локатор не зависит от этих протоколов, они обрабатываются только в реализации ''OberHostFiles''. |
Таким образом, описав сообщение ''GetPathStringMsg'' мы получаем возможность запросить у локатора текстовый путь. | Таким образом, описав сообщение ''GetPathStringMsg'' мы получаем возможность запросить у локатора текстовый путь. |
Также подобные протоколы могут быть описаны в сторонних компонентах. Такие протоколы могут иметь разную детализацию аспектов платформы, тем самым позволяя разработчику гибко регулировать платформо-зависимость своего прикладного компонента. | Также подобные протоколы могут быть описаны в сторонних компонентах. Такие протоколы могут иметь разную детализацию аспектов платформы, тем самым позволяя разработчику гибко регулировать платформо-зависимость своего прикладного компонента. |
<code>VAR loc: Files.Locator; ober: OberFiles.Locator; gpm: OberProtocol.GetPathStringMsg; | <code oberon2> |
| VAR loc: Files.Locator; ober: OberFiles.Locator; gpm: OberProtocol.GetPathStringMsg; |
BEGIN | BEGIN |
loc:=Files.dir.This(''); | loc:=Files.dir.This(''); |
ELSE Log.String('данный тип фс ещё не поддерживается'); Log.Ln; END; | ELSE Log.String('данный тип фс ещё не поддерживается'); Log.Ln; END; |
IF gpm.path#NIL THEN Log.String(gpm.path$); Log.Ln END; | IF gpm.path#NIL THEN Log.String(gpm.path$); Log.Ln END; |
END;</code> | END; |
| </code> |
Но само наличие таких протоколов не гарантирует, что реализация локатора их поддерживает, и это понятно, ведь сообщения это способ ослабления связности компонентов. Однако, в интересах разработчиков реализаций абстрактных интерфейсов поддерживать наибольшее количество протоколов. Такие реализации смогут сообщать клиентам о поддерживаемых протоколах. | Но само наличие таких протоколов не гарантирует, что реализация локатора их поддерживает, и это понятно, ведь сообщения это способ ослабления связности компонентов. Однако, в интересах разработчиков реализаций абстрактных интерфейсов поддерживать наибольшее количество протоколов. Такие реализации смогут сообщать клиентам о поддерживаемых протоколах. |
===== Результаты ===== | ===== Результаты ===== |
Реализовав описанный способ расширения мы решили проблему наращивания функциональности локатора без изменения базового типа, избежав проблему появления хрупкого базового класса с помощью параметрического полиморфизма, а платформо-зависимость клиентских модулей может регулироваться посредством выбора нужного протокола. | Реализовав описанный способ расширения мы решили проблему наращивания функциональности локатора без изменения базового типа, избежав проблему появления хрупкого базового класса с помощью параметрического полиморфизма, а платформо-зависимость клиентских модулей может регулироваться посредством выбора нужного протокола. |
Таким образом, подсистема с набором подобных уточняющих абстракций, размещенная в общеупотребимой (а возможно и стандартной для сборки BlackBox) подсистеме сможет обеспечить развитие возможностей с сохранением обратной совместимости компонентов и интерфейсов. | Таким образом, подсистема с набором подобных уточняющих абстракций, размещенная в общеупотребимой (а возможно и стандартной для сборки **BlackBox**) подсистеме сможет обеспечить развитие возможностей с сохранением обратной совместимости компонентов и интерфейсов. |
===== Пример использования ===== | ===== Пример использования ===== |
Прототип реализации для эталона BlackBox размещен в подсистеме [[https://bitbucket.org/petryxa/sith|Sith]]. | Прототип реализации для эталона **BlackBox** размещен в подсистеме [[https://bitbucket.org/petryxa/sith|Sith]]. |
| |
| |
--- //[[petryxa.clever@gmail.com|Кушнир П. М.]] 2013/12/20 21:34// | --- //[[petryxa.clever@gmail.com|Кушнир П. М.]] 2013/12/20 21:34// |