Здравствуйте, WolfHound, Вы писали:
КЛ>>Пока меня не разубедили — да. WH>Это догма. Догмы до добра не доводят.
Разве ж это догма? Догма — это когда невозможно переубедить. А меня переубедить можно. Правда, на конкретном примере.
WH>Как ты будешь работать с разными реализациями (читай классами) в статически типизированном языке? Если не через интерфейсы?
Само собой, через интерфейсы, абстрактные классы или темплейты. Но ведь это и не говорит о том, что для каждой сущности нужно создавать по 2 — 3 интерфейса.
WH>И того 5 сущьностей: собственное свойство, собственное событие, присоедененное свойство, присоедененное событие и тип.
Допустим, с сущностями все более-менее понятно. А каковы интерфейсы? Вы писали, что их у Вас 10.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Допустим, с сущностями все более-менее понятно. А каковы интерфейсы? Вы писали, что их у Вас 10.
public interface IElementBase
public interface IEventBase : IElementBase
public interface IPropertyBase : IElementBase
public interface IAttachedElement : IElementBase
public interface IElement : IElementBase
public interface IProperty : IPropertyBase, IElement
public interface IEvent : IEventBase, IElement
public interface IAttachedProperty : IPropertyBase, IAttachedElement
public interface IAttachedEvent : IEventBase, IAttachedElement
public interface IType
Первые 5 интерфейсов нужны для фильтрации и чтобы свойства не копипастить. Остальные собственно интерфейсы конкретных сущьностей.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: О наследовании, иерархиях и проектировании (философское)
Прочитал статью довольно давно, много спорных моментов и мест, с которыми я не согласен; но обсуждать их здесь не буду — это мелкие детали. Сама публикация, на мой взгляд, не совсем удачно раскрывает проблему. Однако, сам я пока могу придумать только худьшие варианты
Главное, что с того времени, я нашел несколько подтверждений полезности ориентира на «идеальную систему» на практике. Для решения хорошо изученных, требующих быстрого результата задач, такой подход, вероятно, не самый лучший. Но когда требуется найти решение "неразрешимой" проблемы, это может очень помочь.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, WolfHound, Вы писали:
WH>Первые 5 интерфейсов нужны для фильтрации и чтобы свойства не копипастить. Остальные собственно интерфейсы конкретных сущьностей.
Спасибо! Теперь мне все более-менее понятно.
Мой ответ: Да, именно такой дизайн я не считаю удачным. Он, безусловно, имеет право на существование, как и всякая модель, но, к сожалению, приводит к серьезным проблемам при сопровождении.
Вопрос: На какой стадии работы программы используются приведенные интерфейсы?
На стадии загрузки или сохранения метаданных?
На стадии конструирования объектов ГУИ (диалогов, контролов и т.д.)?
На стадии работы объектов ГУИ (во время показа диалога и т.п.)?
Другое?
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Мой ответ: Да, именно такой дизайн я не считаю удачным. Он, безусловно, имеет право на существование, как и всякая модель, но, к сожалению, приводит к серьезным проблемам при сопровождении.
Интересно к каким?
КЛ>На стадии загрузки или сохранения метаданных?
Эти интерфейсы являются моделью метаданных.
КЛ>На стадии конструирования объектов ГУИ (диалогов, контролов и т.д.)?
Если ты про востановление формы из сериализованного представления то да.
Ибо без метаданных невозможно прочитать то что сохранено.
КЛ>На стадии работы объектов ГУИ (во время показа диалога и т.п.)?
Нет. Ибо тут уже работают связанные в кучу объекты WinForms.
КЛ>Другое?
Во время редактирования формы в дизанере форм.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
КЛ>>Мой ответ: Да, именно такой дизайн я не считаю удачным. Он, безусловно, имеет право на существование, как и всякая модель, но, к сожалению, приводит к серьезным проблемам при сопровождении. WH>Интересно к каким?
Основных проблем две:
Изменение, добавление или удаление отдельного атрибута приводит к реорганизации иерархии.
Злоупотребление оператором преобразования типов (dynamic_cast в C++ или as в C#) и, как результат, нарушение LSP.
Более детально обо всех этих проблемах написано в одной из моих статей.
При использовании интерфейсов возникает еще и третья проблема — изменение прототипа одного из методов интерфейса или добавление метода в интерфейс неминуемо приводит к необходимости изменения во всех реализациях. Это, конечно, характерно для любого интерфейса (например, Win32 API или OpenGL). Но проблема проявляется довольно часто, когда интерфейс строится путем "фильтрации" — когда общие для всех классов свойства выносятся в базовые классы (интерфейсы). Т.е. когда анализируются атрибуты и сходные атрибуты группируются в базовые классы (или интерфейсы).
Все эти проблемы я могу показать и на Вашем примере. Но тогда мне нужно знать, какие операции объявлены в каждом из интерфейсов, чтобы не выдумывать их из головы.
WH>Эти интерфейсы являются моделью метаданных.
Это-то мне понятно. Но я спрашивал немного о другом. На всякий случай, переформулирую вопросы:
Какие обязанности существуют у этой иерархии (целиком)?
Какие обязанности существуют у отдельного интерфейса или класса иерархии? У IElementBase, IPropertyBase, IElement, IAttachedElement, IProperty, IAttachedProperty и т.д.?
Из Вашиз ответов я понял, что обязанности таковы:
Восстановление формы из сериализованного представления.
Сериализация формы.
Редактирование формы (?).
Иное?
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Основных проблем две:
КЛ> КЛ>Изменение, добавление или удаление отдельного атрибута приводит к реорганизации иерархии. КЛ>Злоупотребление оператором преобразования типов (dynamic_cast в C++ или as в C#) и, как результат, нарушение LSP. КЛ>
КЛ>Более детально обо всех этих проблемах написано в одной из моих статей.
КЛ>При использовании интерфейсов возникает еще и третья проблема — изменение прототипа одного из методов интерфейса или добавление метода в интерфейс неминуемо приводит к необходимости изменения во всех реализациях. Это, конечно, характерно для любого интерфейса (например, Win32 API или OpenGL). Но проблема проявляется довольно часто, когда интерфейс строится путем "фильтрации" — когда общие для всех классов свойства выносятся в базовые классы (интерфейсы). Т.е. когда анализируются атрибуты и сходные атрибуты группируются в базовые классы (или интерфейсы).
Кирилл, в том что вы говорите про решения Гради Буча и сейчас пытаетесь сказать про решения WolfHound-а просматривается одна и та же красная нить: мол отгребете вы, ребята, по полной, когда будете вынуждены свои иерархии расширять для поддержки новых требований.
И забываете простую штуку -- для того, чтобы появились эти самые новые требования, нужно здесь и сейчас получить работающее решение той конкретной задачи, которая была поставлена. Не больше, не меньше. Были в задаче Гради Буча именно такие датчики, он их объеденил в иерархию так, чтобы было не сложно и чтобы работало. Макаронный эфект там наблюдается, на вскидку, только в DisplayManager::display и все. Отказ от этого макаронного кода привел бы, скажем, к реализации Visitor-ов и усложнения датчиков. Т.е. решение Буча подчиняется простой идее: вовремя сделать минимально необходимый и минимально сложный код для решения конкретной задачи. Все остальные проблемы должны решаться по мере их поступления.
Вы же со своим стремлением показать, что все в будущем будет плохо и что лучше сразу сделать идеальное решение, являетесь, к сожалению, ярким примером "русских программистов". Вроде как "мы будет долго запрягать, выдумывая идеальное решение, зато потом быстро доедем".
Мне как-то рассказывали на фирме Sun, что когда в 1995 году оставалось три дня до сдачи «Соляриса», им нужен был тест для Фортран-транслятора. Послали в Новосибирск заказ (у Sun была там своя группа) — сделать за два дня тест. Через неделю получили ответ, что через месяц будет замечательный тест на все случаи жизни.
Вообще-то говоря, перепроектирование и изменение иерархий -- это совершенно нормальный процесс разработки ПО. Ничего страшного в нем нет. Создавать сразу устойчивые к изменению требований системы возможно, вероятно, только для тчательно изученных предметных областей, имея за плечами большое количество аналогичных проектов. Только не всегда это возможно. Хотя бы потому, что всем нам время от времени приходится менять сферу деятельности. И учиться чему-то с нуля, при этом от нас требуется создание работающих систем в конкретные сроки по вполне конкретным требованиям.
Кстати, отсылки к вашим предыдущим статьям выглядят как-то несолидно. Пора бы уже такой же толмуд по проектированию идеальных систем написать, как Буч по ОО проектированию. Вот ссылки на него будут выглядеть гораздо солиднее.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Кирилл, в том что вы говорите про решения Гради Буча и сейчас пытаетесь сказать про решения WolfHound-а просматривается одна и та же красная нить: мол отгребете вы, ребята, по полной, когда будете вынуждены свои иерархии расширять для поддержки новых требований.
К сожалению, как правило, "огребают" сопровождающий программист и компания, разрабатывающая программу, т.к. в связи с тем, что модель не расширяема, компании приходится либо отказываться от расширения функциональности, либо вкладывать кучу денег в то, чтобы полностью переделать решение. Последнее особенно несправедливо, т.к. расширяемость такого решения декларировалась разработчиком (там же интерфейсы, для них всегда можно создать другую реализацию).
E>И забываете простую штуку -- для того, чтобы появились эти самые новые требования, нужно здесь и сейчас получить работающее решение той конкретной задачи, которая была поставлена. Не больше, не меньше.
Расширяемость и повторное использование являются одними из критериев качества программы (привожу ссылку на классика ). Думаю, это не стоит сбрасывать со счетов.
E>Были в задаче Гради Буча именно такие датчики, он их объеденил в иерархию так, чтобы было не сложно и чтобы работало. Макаронный эфект там наблюдается, на вскидку, только в DisplayManager::display и все. Отказ от этого макаронного кода привел бы, скажем, к реализации Visitor-ов и усложнения датчиков. Т.е. решение Буча подчиняется простой идее: вовремя сделать минимально необходимый и минимально сложный код для решения конкретной задачи. Все остальные проблемы должны решаться по мере их поступления.
Если "плясать" от предложенной ОО-модели, то, действительно, ничего, кроме dynamic_cast'ов или Visitor'ов не остается. Но эти проблемы — прямое следствие предложенной модели. Если модель переделать, то код не усложниться, а dynamic_cast'ы и Visitor'ы не понадобятся.
Решение существует и для задачи с датчиками, и для задачи с кнопками и итемами. Если WolfHound'у будет интересно, это новое решение можно будет обсудить.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>К сожалению, как правило, "огребают" сопровождающий программист и компания, разрабатывающая программу, т.к. в связи с тем, что модель не расширяема, компании приходится либо отказываться от расширения функциональности, либо вкладывать кучу денег в то, чтобы полностью переделать решение. Последнее особенно несправедливо, т.к. расширяемость такого решения декларировалась разработчиком (там же интерфейсы, для них всегда можно создать другую реализацию).
Не нужно забывать, что все это происходит на фоне получения прибыли от продажи предыдущей, пусть даже не очень удачной, но зато работающей версии.
E>>Были в задаче Гради Буча именно такие датчики, он их объеденил в иерархию так, чтобы было не сложно и чтобы работало. Макаронный эфект там наблюдается, на вскидку, только в DisplayManager::display и все. Отказ от этого макаронного кода привел бы, скажем, к реализации Visitor-ов и усложнения датчиков. Т.е. решение Буча подчиняется простой идее: вовремя сделать минимально необходимый и минимально сложный код для решения конкретной задачи. Все остальные проблемы должны решаться по мере их поступления. КЛ>Если "плясать" от предложенной ОО-модели, то, действительно, ничего, кроме dynamic_cast'ов или Visitor'ов не остается. Но эти проблемы — прямое следствие предложенной модели. Если модель переделать, то код не усложниться, а dynamic_cast'ы и Visitor'ы не понадобятся.
КЛ>Решение существует и для задачи с датчиками, и для задачи с кнопками и итемами. Если WolfHound'у будет интересно, это новое решение можно будет обсудить.
Ну так приведите решение задачи о метеорологической станции из книги Буча. Хотя бы в таком же количестве фрагментов кода, как это сделано у Буча с соответствующими пояснениями. Тогда и будет видно, что к чему.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Изменение, добавление или удаление отдельного атрибута приводит к реорганизации иерархии.
Это ты к чему?
КЛ>Злоупотребление оператором преобразования типов (dynamic_cast в C++ или as в C#) и, как результат, нарушение LSP.
Это догма.
Вот скажи мне зачем нужно заводить 9 коллекций когда можно обойтись одной с фильтрацией?
того к чему приводят догмы. В этой статье написан клькулятор на C# по всем канонам ООП. И тоже самое на nemerle.
Я думаю не вызывает сомнений какой вариант предпочтительней.
КЛ>При использовании интерфейсов возникает еще и третья проблема — изменение прототипа одного из методов интерфейса или добавление метода в интерфейс неминуемо приводит к необходимости изменения во всех реализациях. Это, конечно, характерно для любого интерфейса (например, Win32 API или OpenGL). Но проблема проявляется довольно часто, когда интерфейс строится путем "фильтрации" — когда общие для всех классов свойства выносятся в базовые классы (интерфейсы). Т.е. когда анализируются атрибуты и сходные атрибуты группируются в базовые классы (или интерфейсы).
В базовые интерфейсы выносилось только то что к этим интерфейсам относится по смыслу.
Например в IElement вобще нет ни свойств, ни методов, ни событий. Он нужен для того чтобы можно было отфильтровать все собственные элементы.
КЛ>Какие обязанности существуют у этой иерархии (целиком)?
Я уже сказал. Это модель метаданных.
Метаданные нужны для того чтобы работать с данными.
КЛ>Какие обязанности существуют у отдельного интерфейса или класса иерархии? У IElementBase, IPropertyBase, IElement, IAttachedElement, IProperty, IAttachedProperty и т.д.?
Описание части модели.
КЛ>Из Вашиз ответов я понял, что обязанности таковы:
Зачем она нужна я уже написал в этом
Здравствуйте, WolfHound, Вы писали:
WH>Можешь предложить свой вариант.
Хорошо. Вы можете расписать Ваши интерфейсы целиком (с объявлениями методов)? Мне это нужно, чтобы не заниматься догадками.
WH>А я раскажу о его реальных проблемах, а не выдуманных на основе догм.
Расскажите. Будет интересно. Кстати, описываемые мной проблемы тоже увы реальны. И, конечно же, они не выдуманы на основе догм.
Здравствуйте, Кирилл Лебедев, Вы писали:
WH>>Можешь предложить свой вариант. КЛ>Хорошо. Вы можете расписать Ваши интерфейсы целиком (с объявлениями методов)? Мне это нужно, чтобы не заниматься догадками.
А зачем собственно? Я дал постановку задачи.
Зачем тебе мое кривое решение для того чтобы спроектировать прямое?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>>Злоупотребление оператором преобразования типов (dynamic_cast в C++ или as в C#) и, как результат, нарушение LSP. WH>Это догма. WH>Вот скажи мне зачем нужно заводить 9 коллекций когда можно обойтись одной с фильтрацией? WH>Вот пример
того к чему приводят догмы. В этой статье написан клькулятор на C# по всем канонам ООП. И тоже самое на nemerle. WH>Я думаю не вызывает сомнений какой вариант предпочтительней.
WH>Можешь предложить свой вариант. А я раскажу о его реальных проблемах, а не выдуманных на основе догм.
Еще по теме хорошая статейка, где на scala рассматриваются два варианта реализации вычислителя в стороготипизированном языке и анализ проблем (а так же их преодоление )
Ставится задача:
• Extensibility in both dimensions: It should be possible
to add new data variants and adapt existing opera-
tions accordingly. Furthermore, it should be possible
to introduce new processors.
• Strong static type safety: It should be impossible to
apply a processor to a data variant which it cannot
handle.
• No modification or duplication: Existing code should
neither be modified nor duplicated.
• Separate compilation: Compiling datatype exten-
sions or adding new processors should not encom-
pass re-type-checking the original datatype or exist-
ing processors.
• Independent extensibility: It should be possible
to combine independently developed extensions so
that they can be used jointly [21].
И решается Object-Oriented Decomposition и Functional Decomposition с примерами расширения в двух направлениях: по данным и по операциям. Там же к стати приведены ссылки и краткое описание частичных способов решения.
Т.е. суть поста в том, что проблема не в ООП как таковом, а в существующих реализациях. При реализации на "правильном" языке все эти проблемы "иерархий" решаются более эффективно и расширяемо. И мне лично данная статья оказалась в N раз полезнее, чем обсуждаемая в топике.
непонятно, что нужно сделать. Вы описали лишь частную проблему с кнопкой и что есть некая объектная модель. Однако для чего — для решения какой задачи — эта модель создается, Вы умолчали.
Есть предположение, что Вы создаете редактор форм и систему, которая автоматически создает их по метаописанию. Но зачем гадать, когда можно узнать назначение системы у Вас?
WH>Зачем тебе мое кривое решение для того чтобы спроектировать прямое?
Для того, чтобы понять, какие действия выполняют приведенные интерфейсы (и классы) и за что, конкретно, они отвечают.
Если не хотите приводить описание интерфейсов, то, пожалуйста, ответьте на вопрос: Назовите главную полезную функцию проектируемой системы?
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Для того, чтобы понять, какие действия выполняют приведенные интерфейсы (и классы) и за что, конкретно, они отвечают.
Из модели метаданных ты это не поймешь.
Ибо модель очень абстрактна и вобще ничего не знает о кнопках и тп.
КЛ>Если не хотите приводить описание интерфейсов, то, пожалуйста, ответьте на вопрос: Назовите главную полезную функцию проектируемой системы?
1)Нужно иметь возможность отображать формы где попало (win, web...)
2)Нужно иметь возможность сохранать формы где попало. XML, RDB...
3)Нужен редактор форм.
4)Различные лейауты необходимы и точка. Те нужен и AbsolutePosition и Grid и много чего еще.
Нужно спроектировать модель метаданных, и для примера кнопку и грид.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, aka50, Вы писали:
A>Еще по теме хорошая статейка, где на scala рассматриваются два варианта реализации вычислителя в стороготипизированном языке и анализ проблем (а так же их преодоление )
Нашлась бы добрая душа, да на пальцах бы объяснила, в чем смысл рассматриваемой в этом tech report-е проблемы. И чтобы примеры были более жизненные, а не Plus, PlusNeg и DblPlusNeg.
А то все закручено, заморочено и сложно понять, нужно это вообще или нет?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, aka50, Вы писали:
A>>Еще по теме хорошая статейка, где на scala рассматриваются два варианта реализации вычислителя в стороготипизированном языке и анализ проблем (а так же их преодоление )
E>Нашлась бы добрая душа, да на пальцах бы объяснила, в чем смысл рассматриваемой в этом tech report-е проблемы. И чтобы примеры были более жизненные, а не Plus, PlusNeg и DblPlusNeg.
E>А то все закручено, заморочено и сложно понять, нужно это вообще или нет?
Ну да... замороченно там... немного , могу посоветовать еще вот это статейку, после нее должно быть понятнее http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf
А вообще на всей этой технологии self/this/super у них компилятор спроектрирован. Так что "реальный" пример можно прям в исходниках самого компилятора посмотреть.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, aka50, Вы писали:
A>>Еще по теме хорошая статейка, где на scala рассматриваются два варианта реализации вычислителя в стороготипизированном языке и анализ проблем (а так же их преодоление )
E>Нашлась бы добрая душа, да на пальцах бы объяснила, в чем смысл рассматриваемой в этом tech report-е проблемы. И чтобы примеры были более жизненные, а не Plus, PlusNeg и DblPlusNeg.
E>А то все закручено, заморочено и сложно понять, нужно это вообще или нет?
А если в кратце, то там описывается техника deep mixin composition, т.е. глубокая модификация иерархии путем подмешивания в нее нужно функциональности. Т.е. например у нас есть некий базовый функционал, но кодом, подобным
trait Show extends Base {
type exp <: Exp;
trait Exp extends super.Exp {
def show: String;
}
class Num(v: int) extends super.Num(v) with Exp {
def show = value.toString();
}
}
можно зменять коревые классы иерархии (в данном случае в базовый класс Exp мы подмешиваем дополнительную операцию show) при этом все это делается со статической проверкой типов, а следовательно если объявить show как abstract мы автоматом получим ошибки компиляции для тех комбинаций mixin-ов, где какой-то наследник (возможно тоже в свою очередь "подмешанный") не реализует этот метод, но и это не проблема, т.к. мы может доопределить эти методы по месту, например так:
trait ShowPlus extends BasePlus with Show {
class Plus(l: exp, r: exp) extends super.Plus(l, r)
with Exp {
def show = left.show + "+" + right.show;
}
}
И более того, там же расписано, каким образом можно объединять иерархии в один большой компонент (правда довольно многословно, но надеюсь приделают к этому делу сахар какойнить)
trait ShowDblePlusNeg extends ShowPlus
with DblePlus {
type exp <: Exp;
trait Exp extends super[ShowPlus].Exp
with super[DblePlus].Exp;
class Num(v: int)
extends super[ShowPlus].Num(v)
with super[DblePlus].Num(v)
with Exp;
class Plus(l: exp, r: exp)
extends super[ShowPlus].Plus(l, r)
with super[DblePlus].Plus(l, r)
with Exp;
}
Это все что я привел, для object-oriented decomposition. Т.е. для данного подхода сложно добавить новый метод (т.к. приходится переопределять Exp в все ирерахии), но легко добавлять нового наследника Exp.
Там же рассматривается fucntion decomposion (т.е. проще говоря visitor), там проще добавлять методы, но сложнее соотвественно данные.
Собственно суть статьи, что без изменения базовой иерархии можно создавать новые, при этом изменяя все, вплоть до корнвевых базовых классов (таких как Exp), чего в обычных языках типа Java делать крайне затруднительно.
Здравствуйте, aka50, Вы писали:
A>Собственно суть статьи, что без изменения базовой иерархии можно создавать новые, при этом изменяя все, вплоть до корнвевых базовых классов (таких как Exp), чего в обычных языках типа Java делать крайне затруднительно.
Ну об этом-то там прямо во вступлении говорится. Мне бы понять, где вся эта байда на практике применяться может.
От создания компиляторов я далек. Вот на примере GUI-ев каких-нибудь или сетевого взаимодействия примеры бы какие-нибудь посмотреть бы...
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>От создания компиляторов я далек. Вот на примере GUI-ев каких-нибудь или сетевого взаимодействия примеры бы какие-нибудь посмотреть бы...
Ну непосредственно к сетевому коду или гуям в общем-то это слабо прикручивается, там рулит паттерн-матчинг и прочие implicit фишки (если конкретно скала рассматривать), а вот в деле фреймворко-компоненто-строения — вполне себе замечательная технология (хотя и не лишенная недостатков, например в том же компиляторе за счет всех эти self и type образуется довольно сильная связанность и например выцепить отдельно SyntaxAnalyzer без всей остальной ботвы довольно сложно)
Если попытаться порассуждать на каком-то конкретном примере, то например при соотвествующем проектировании можно просто расширяя иерархию например твоего sobjectizer можно было бы внедряться, и даже переопределять, часть функциональности, при этом не нужно никаких ухищрений типа паттерна CoR. И более того, переопределенный фреймворк можно сделать несоместимым (например по генерируемым объектам-сообщениям) с базовым, что дает определенную гарантию typesafe системы (хотя может и определенные сложности привнести).
А вообще надо бы и правда попробывать чтонить более близкое к людям рассмотреть как пример... правда это уже на целую статью тянет, тут одним постом не отделаешься