Например.
Рисую я на модели элемент со стереотипом "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*
Комментариев нет:
Отправить комментарий