вторник, 27 октября 2009 г.

Реализация зависимостей в форме ввода

Сегодня набросал механизм зависимостей. Вроде работает, но внутреннее чувство неправильности сделанного осталось.
Мне не нравится, что я использовал:
- множественное наследование
- RTTI

Это ведет к усложнению проекта. Проект должен быть прост и красив, но сделать просто очень трудно.

Дальше технические детали.


Сначала нужно понять как происходит формирование зависимостей между компонентами.
1) Форма считывает свой файл описания и создает согласно описанию компоненты. Компоненты размещаются в QVector<AbstractFormComponent *> components_;

2) Форма смотрит свойства компонентов и определяет по именам зависимые компоненты.
Например, для компонента Sex (Пол) свойство DependentFields содержит имена LastName, FirstName. Это значит, что выбор пола влияет на компоненты с именами LastName, FirstName.

Теперь нужно определить правила, по которым происходят изменения. Для этого я определил класс Rule.

class Rule
{
public:
static void applyRule(const AbstractFormComponent & master, AbstractFormComponent & slave);

static void apply(const FSexEdit & sex, FComboTextList & combo);
};



Этот класс - утилита класса AbstractFormComponent. Функция applyRule() принимает указатель на ведущий (master) и ведомый компонент (slave).
Далее, используя RTTI dynamic_cast она определяет тип компонентов и вызывает перегружаемую функцию apply(...).

Это первый минус. Не хотелось бы использовать RTTI, но попытки сделать через шаблоны провалились. Поэтому пока так.

Далее, заводим класс DependentManager, управляющий зависимостями. В его обязанности входит хранение QMultiMap<AbstractFormComponent * master, AbstractFormComponent * slave>

Экземпляр класса DependentManager должен быть в форме один.

И наконец, создаем класс-примесь Dependent, который будем примешивать к наследникам AbstractFormComponent для задания им возможности работать с DependentManager.

Вот здесь вырисовывается второй минус - множественное наследование.

Компонент выбора пола выглядит так

class FSexEdit : public QObject, public AbstractFormComponent, public Dependent


QObject нужен для приема сигналов от композитного компонента SexEdit. AbstractFormComponent - основной супер-класс, Dependent - примесь.

В принципе ничего сверх страшного, но изящество и простота катастрофически тают уже в начале проекта. А это грозит усложнением дальнейшего сопровождения.

Комментариев нет:

Отправить комментарий