Ну, так или иначе все эти MFC-двойники уже не вставляют... ладно, в самом деле.
Традиционное GUI-приложение обычно устроено как большая, сильно полиморфная иерархия классов. Нередко в этом процессе задействован набор хорошо проработанных схем дизайна. В поддержку такой стратегии разработки созданы несколько огромных иерархических фреймворков, таких как MFC, wxWindows и т.д. Эти фреймворки содержат набор стандартных элементов GUI, которые можно использовать как базовые классы. Этот подход ("наследование") можно проиллюстрировать на примере с подгонкой фона кнопки.
//обычная
кнопка
struct button
{
...свойства обычной кнопки
};
//кнопка
с возможностью задать цвет фона
struct button_with_custom_background
: button
{
...задать цвет фона
};
Допустим, нам понадобилась стандартная кнопка с картинкой. Мы можем создать другой класс кнопки.
Это сработало, но что если потом нам понадобится стандартная кнопка с возможностью задания цвета фона и картинкой. Очевидно, мы не сможем написать:
Здесь проиллюстрирована общая проблема полиморфного наследования. Конечно, можно задействовать указатели, но это не будет хорошо выглядеть. Типобезопасность таких фреймворков не очень сильна, мягко говоря. Нотус предполагает другой подход. Он может быть описан как процесс задания набора взаимозаменяемых "деталей" GUI. Затем компилятор C++ генерирует и соединяет эти детали в соответствии с их спецификациями. Разумеется, спецификации описаны на языке шаблонов C++. Идея напоминает процесс промышленного производства, например такое, как разработка и создание автомобиля. В рассмотренном выше примере подход Нотус выглядел бы как следующий псевдокод.
Мы создали две взаимозаменяемые детали GUI. Они взаимозаменяемые, так как могут использоваться с любым окном, не только с кнопками, и легко могут быть заменены другой реализацией. Теперь мы можем соединить все детали вместе любым удобным нам способом.
typedef
view< button
, my_background
> button_with_custom_background;
typedef
view< button
, my_image
> button_with_image;
typedef
view< button
, my_background
, my_image
> button_with_background_and_image;
Мы можем сделать другие детали, например строку ввода с возможностью задания цвета фона.
typedef
view< edit
, my_background
> edit_with_custom_background;
Since the final structure of the GUI application is generated at compile time, polymorphism is not an essential requirement anymore. Indeed, polymorphism is a way to abstract or classify a concrete class. Polymorphism is essential for traditional object oriented design because otherwise, we would have to implement separate routines for all possible concrete classes. With templates, we can just use the concrete classes directly and the compiler will generate code for each of the concrete combinations as needed. In Notus, a virtual method is an exception, not a rule.
Компилятор проверяет, что все детали подходят друг к другу. Так что, потенциально мы имеем очень сильную типобезопасность. Если компилятор смог состыковать всё вместе, то весьма вероятно, что программа будет намного стабильнее.
© Copyright Евгений Гладышев, 2004