Например.
Рисую я на модели элемент со стереотипом "LocalConst". Это коробка с локализованными строками.
На самом деле она порождает собой другую коробку - "Consts" ну и другие сопутствующие элементы, типа "ключей для локализации", а также другую подобную инфраструктуру.
И эти "порождаемые" элементы - делает кодогенератор. И они доступны пользователю, как если бы он их нарисовал бы руками.
А если "родительские" элементы удаляются или переезжают в другое место, то и "порождаемые элементы" испытывают соответствующую трансформацию.
Или вот есть стереотип "TestTarget". Он указывает на "Target". На приложение, для которого делаются эти тесты.
Так вот - можно рисовать руками все внутренности TestTarget'а. Если требуется так скажем "fine tuning".
А можно оставить его пустым. Просто поставив соответствующую стрелку на модели.
И все "кишки" данного TestTarget'а кодогенератор породит САМ. Так как указано в мета-модели.
С одной стороны и гибкость - можно всё настроить "руками", а с другой стороны - "стандартные шаблонные решения".
Ну или банально. Есть стереотипа "Form". Так вот по-умолчанию ему можно не ставить связь наследования к TForm из стандартной библиотеки. Кодогенератор её сам подставит. При этом - будет возможность переопределять соответствующие методы базового класса. А если нас такое наследование не устраивает - мы можем поставить ДРУГОЕ, но уже - руками.
Вот как-то так.
Про LocalConst пример вот такой:
Рисую я на модели элемент со стереотипом "LocalConst". Это коробка с локализованными строками.
На самом деле она порождает собой другую коробку - "Consts" ну и другие сопутствующие элементы, типа "ключей для локализации", а также другую подобную инфраструктуру.
И эти "порождаемые" элементы - делает кодогенератор. И они доступны пользователю, как если бы он их нарисовал бы руками.
А если "родительские" элементы удаляются или переезжают в другое место, то и "порождаемые элементы" испытывают соответствующую трансформацию.
Или вот есть стереотип "TestTarget". Он указывает на "Target". На приложение, для которого делаются эти тесты.
Так вот - можно рисовать руками все внутренности TestTarget'а. Если требуется так скажем "fine tuning".
А можно оставить его пустым. Просто поставив соответствующую стрелку на модели.
И все "кишки" данного TestTarget'а кодогенератор породит САМ. Так как указано в мета-модели.
С одной стороны и гибкость - можно всё настроить "руками", а с другой стороны - "стандартные шаблонные решения".
Ну или банально. Есть стереотипа "Form". Так вот по-умолчанию ему можно не ставить связь наследования к TForm из стандартной библиотеки. Кодогенератор её сам подставит. При этом - будет возможность переопределять соответствующие методы базового класса. А если нас такое наследование не устраивает - мы можем поставить ДРУГОЕ, но уже - руками.
Вот как-то так.
Про LocalConst пример вот такой:
// перекрытие базового стереотипа Delphi интерфейсы и реализация::MDAGenerator %f _DoSpell //#UC START# *4B2A19E3038Bfor4B386A11030E* %S%[inherited]\ [{"%{Tl3StringIDEx}N"=""}%f_find_element(Tl3StringIDEx,Tl3StringIDEx)]\ [{"%{Tl3MessageID}N"=""}%f_find_element(Tl3MessageID,Tl3MessageID)]\ [{"%{Dialogs}N"=""}%f_find_element(4AB0EE02004E,Dialogs)]\ // <{}{%C#f_IsMessage()=true}\ // %C<{}{%C#f_IsChoices()=true}\ // %C%f_DoSpell()>\ // >\ %f_set_var(FOUND,"false")\ %f_set_var(PARENT,"")\ <{}{%P#f_IsClassBase()=true|%P#f_IsUtilityPack()=true}{%P}\ [{%{FOUND}N=false}\ %f_set_var(FOUND,"true")\ %f_set_var(PARENT,P)\ ]\ >\ %{PARENT}%f_make_accessable(%{Tl3StringIDEx}U)\ %{PARENT}%f_make_accessable(%{Tl3MessageID}U)\ [{%{PARENT}C=Class}\ %{PARENT}%f_add_dependency(%SU_%{Tl3StringIDEx}U_uses,%{Tl3StringIDEx}U,uses,,USES_Inst)\ %{PARENT}%f_add_dependency(%SU_%{Tl3MessageID}U_uses,%{Tl3MessageID}U,uses,,USES_Inst)\ ]\ %{PARENT}%f_add_class(%SU_%{Tl3StringIDEx}U_LCImpl,Constants,LCImpl[{%S#f_IsChoices()=true}_%PN_]%SN,LocalConst_Inst)\ %{LocalConst_Inst}%f_set_visibility_type(%SV)\ [{%S#f_IsChoices()=true}{\ %{LocalConst_Inst}%f_set_documentation(Локализуемые строки %SN)\ }\ %{LocalConst_Inst}%f_set_documentation(Варианты выбора для диалога %PN)\ ]\ %{LocalConst_Inst}%f_set_up(TreatAsVars,true)\ // - шаманство, чтобы превратить константы в переменные %{LocalConst_Inst}%f_set_up(ifdef,%S{ifdef})\ %{LocalConst_Inst}%f_set_up(ifndef,%S{ifndef})\ %{LocalConst_Inst}%f_set_up(children prefix,%S{children prefix})\ %{LocalConst_Inst}%f_set_up(elements prefix,str[_%S{elements prefix}])\ %f_set_var(WAS_USES_TO_DIALOGS,"false")\ <{}{}{%C}\ [{%C#f_IsMessage()=true}{\ %f_set_var(CONST_TYPE,{Tl3StringIDEx})\ }\ [{%{WAS_USES_TO_DIALOGS}N!=true}\ %{PARENT}%f_make_accessable(%{Dialogs}U)\ %f_set_var(WAS_USES_TO_DIALOGS,"true")\ %{PARENT}%f_add_dependency(%SU_%{Tl3MessageID}U_uses_Dialogs,%{Dialogs}U,uses,,USES_Inst)\ ]\ %f_set_var(CONST_TYPE,{Tl3MessageID})\ ]\ %{LocalConst_Inst}%f_add_attribute(%{LocalConst_Inst}U_%CU_Impl,,%C#f_AdditionalPrefix()%f_N(%C) :\ %{CONST_TYPE}U = (rS : -1; rLocalized : false;\ rKey : '%C%f_pas_Prefix()%C#f_AdditionalPrefix()%f_N(%C)';\ rValue : \ [{"%CD"=""|%C#f_CanUseDocAsValue()!=true}{\ // ^ - ибо UserType'ы неправильно выливаются %CD\ }\ [{"%C{Value}"=""}{\ %C{Value}\ }\ %C%VN\ ]\ ]\ ),Attr_Inst)\ %{Attr_Inst}%f_set_visibility_type(%CV)\ %{Attr_Inst}%f_set_documentation([{}{%C{Value}}[{}{%C%VN}%CD]])\ %{Attr_Inst}%f_set_up(ifdef,%C{ifdef})\ %{Attr_Inst}%f_set_up(ifndef,%C{ifndef})\ %{PARENT}%f_add_operation(%CU_Init,ini,Init_%f_N(%{Attr_Inst}) (),Op_Instance)\ %{Op_Instance}%f_set_documentation(Инициализация %{Attr_Inst}%f_pas_Prefix()%f_N(%{Attr_Inst}))\ %{Op_Instance}%f_set_abstraction_type(final)\ %{Op_Instance}%f_set_visibility_type(PrivateAccess)\ [{"%S{ifdef}"!=""}{\ %f_set_var(IFDEF_VALUE,"%C{ifdef}")\ }\ [{"%C{ifdef}"!=""}{\ %f_set_var(IFDEF_VALUE,"%S{ifdef}")\ }\ %f_set_var(IFDEF_VALUE,"%S{ifdef},%C{ifdef}")\ ]\ ]\ %{Op_Instance}%f_set_up(ifdef,%{IFDEF_VALUE}N)\ [{"%S{ifndef}"!=""}{\ %f_set_var(IFDEF_VALUE,"%C{ifndef}")\ }\ [{"%C{ifndef}"!=""}{\ %f_set_var(IFDEF_VALUE,"%S{ifndef}")\ }\ %f_set_var(IFDEF_VALUE,"%S{ifndef},%C{ifndef}")\ ]\ ]\ %{Op_Instance}%f_set_up(ifndef,%{IFDEF_VALUE}N)\ %{Op_Instance}%f_set_uc_content(intf.pas,,\ %{Attr_Inst}%f_pas_Prefix()%f_N(%{Attr_Inst}).Init;\ %C%f_AdditionalInitCode("%{Attr_Inst}%f_pas_Prefix()%f_N(%{Attr_Inst})")\ )\ >\ [{%Gx=true}\ %{PARENT}%f_add_class(%SU_%{CONST_TYPE}U_LCConstArr,ConstantArray,%SNMap,LocalConstArray_Inst)\ [{"%{Pl3StringIDEx}N"=""}%f_find_element(Pl3StringIDEx,Pl3StringIDEx)]\ %{LocalConstArray_Inst}%f_add_inheritable(%{Pl3StringIDEx}U)\ %{LocalConstArray_Inst}%f_add_realized(%GU)\ %{LocalConstArray_Inst}%f_set_up(ifdef,%S{ifdef})\ %{LocalConstArray_Inst}%f_set_up(ifndef,%S{ifndef})\ %{LocalConstArray_Inst}%f_set_visibility_type(%SV)\ %{LocalConstArray_Inst}%f_set_documentation(Карта преобразования локализованных строк %SN)\ %{LocalConstArray_Inst}%f_set_up(Need mapping support,%S{Need mapping support})\ %{LocalConstArray_Inst}%f_set_up(Need map interface,%S{Need map interface})\ %{LocalConst_Inst}<{}{}{%C}\ %{LocalConstArray_Inst}%f_add_attribute(%CU_Arr,,%f_N(%C) :\ %{Pl3StringIDEx}U = %{LocalConst_Inst}N::%CN,Attr_Inst)\ >\ ] //#UC END# *4B2A19E3038Bfor4B386A11030E*
Комментариев нет:
Отправить комментарий