Что такое QueryInterface и Supports с моей точки зрения?
Это "своего рода" - "типизированный Duck-Typing". Когда от одного объекта - "неожиданно" рождается "другой".
Именно "рождается". Семантика метода - это предполагает.
Вещь - БЕЗУСЛОВНО полезная и гибкая.
И решает множество задач.
Но! Ставить во главу архитектурных решений подобный подход - я считаю ошибкой.
Кроме потери эффективности, на которую может быть и можно закрыть глаза, это ведёт к "косвенным зависимостям". Описанным "только" в документации.
Метод "секретного тут-тук".
Практические примеры - есть у меня перед глазами.
Далеко ходить не надо:
Это "своего рода" - "типизированный Duck-Typing". Когда от одного объекта - "неожиданно" рождается "другой".
Именно "рождается". Семантика метода - это предполагает.
Вещь - БЕЗУСЛОВНО полезная и гибкая.
И решает множество задач.
Но! Ставить во главу архитектурных решений подобный подход - я считаю ошибкой.
Кроме потери эффективности, на которую может быть и можно закрыть глаза, это ведёт к "косвенным зависимостям". Описанным "только" в документации.
Метод "секретного тут-тук".
Практические примеры - есть у меня перед глазами.
Далеко ходить не надо:
Supports(BorlandIDEServices, IOTAModuleServices, Result); IBorlandIDEServices = interface(IUnknown) ['{7FD1CE92-E053-11D1-AB0B-00C04FB16FB3}'] end; (* The BorlandIDEServices global variable is initialized by the Delphi or C++Builder IDE. From this interface all of the IxxxxServices interfaces may be queried for. For example, in order to obtain the IOTAModuleServices interface, simply call the QueryInterface method with the interface identifier or the GUID for the IOTAModuleServices interface. In Delphi, you could also use the "as" operator, however not all versions of the IDEs will support all the "services" interfaces. IOTATodoServices is only supported in the Professional and Enterprise versions of the products. In Delphi; var ModuleServices: IOTAModuleServices; ... if Supports(BorlandIDEServices, IOTAModuleServices, ModuleServices) then begin ... end; or in C++Builder; IOTAModuleServices *ModuleServices; if (Supports(BorlandIDEServices, __uuidof(IOTAModuleServices), &ModuleServices)) { ... } *)
-- ну НЕ дружелюбен такой подход к использующим его.
Почему нельзя ЯВНО возвращать те или иные интерфейсы, через ЯВНЫЕ методы AsIxxxxServices - лично я - НЕ ПОНИМАЮ.
И к сожалению примеров ТАКОЙ архитектуры - масса.
И главное, что разработчики "срисовывают" друг у друга подобные подходы. Зачем-то.
Я сам - "срисовывал". Пока не убедился в "порочности" подобной архитектуры.
Пример из Борланда приведён не потому, что у меня "претензии" именно к Борланду, а потому, что он реален и общеизвестен. Чтобы меня не упрекнули в "очередном велосипеде".
И как раз-таки "почему так Борланд" сделал - я "понимаю".
И как раз-таки "почему так Борланд" сделал - я "понимаю".
Комментариев и мнений - не жду. Я написал СВОЁ МНЕНИЕ. Подтверждённое практикой.
"Теория Маркса всесильна потому, что она верна".
Комментариев нет:
Отправить комментарий