Мнения об элементе списка и его классе дизайна - PullRequest
0 голосов
/ 19 сентября 2009

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

У меня уже есть реализация для флажка. Имеет 2 состояния (проверено / не проверено) и 5 ​​подсостояний: нормальное, зависание / активное, размытие, отключено и в состоянии перехода. Шаблон флажка имеет свойства текста, значок (необязательно) и рамку (может быть изменяемого размера). Есть также переходы между состояниями и состояниями. Обе иконки и границы являются анимируемыми.

Меня беспокоит вопрос списка. Они очень похожи на флажки. Поэтому я планирую использовать шаблон флажков для списочных элементов. Однако мне требуется четыре режима элемента списка: простой (только текст), со значком, с флажком и с переключателем (переключатель получен из флажка и интерфейса IRadioButton). Вот его структура:

IWidgetObject
      |
   Checkbox       IRadioButton
      \                /
       `--------------´
              |
         RadioButton

Я хочу реализовать что-то вроде этого. ListItemBase должен быть производным от IWidgetObject. Это логично или есть лучшие альтернативы.

  class ListItemBase : public Checkbox {
      void Select() { do something; Checkbox::check(); }
  } 

  //This listitem type will have a checkbox without any text
  class ListItemCheckbox : public ListItemBase, private Checkbox {
      check() { update parents checked list; Checkbox::check(); }
  }

  class ListItemRadio : public ListItemBase, private RadioButton, public IRadioButton {
      //here is the problem
  }

ListItemRadio будет иметь 2 различные функции флажка, также я хочу скрыть функцию check () ListItemBase (чтобы переименовать ее). Тогда я должен реализовать это таким образом?

  class ListItemBase : private Checkbox, public IWidgetObject {
      void Select() { do something; Checkbox::check(); }

      //does this even works? (layer is a variable)
      using Checkbox::layer;
  } 

  //This listitem type will have a checkbox without any text
  class ListItemCheckbox : public ListItemBase, private Checkbox {
      check() { update parents checked list; Checkbox::check(); }
  }

  class ListItemRadio : public ListItemBase, private RadioButton, public IRadioButton {
      //here is the problem
  }

Но на этот раз у меня есть 2 объекта IWidget в ListItemRadio, которые я должен преодолеть, реализовав общие функции. Но ListItemBase должен будет сопоставить все элементы IWidgetObject с флажками.

Можно ли использовать виртуальное наследование для решения этих проблем, например, делегирование дочернему классу (флажок). Существует также еще одна проблема, хотя IWidgetObject выглядит как интерфейс, с годами он приобрел некоторые общие реализации, но я не думаю, что это будет проблемой.

Также есть еще одна проблема. Класс флажка имеет нетривиальный конструктор. Можно ли написать что-то вроде этого:

 ListItemBase(IWidgetContainer &container, CheckboxBP &blueprint) : 
        Checkbox(container, blueprint), IWidgetObject(this) {
 }

Это решит множество проблем. Любая идея приветствуется.

Спасибо, что даже прочитали все эти

Ответы [ 2 ]

2 голосов
/ 19 сентября 2009

Я не знаю деталей вашего "движка виджетов" и "шаблонов", так что, возможно, вы разработали это таким образом, что теперь выжимаете руку (надеюсь, нет!), Но мне кажется, что вы ' Использование наследования, когда естественный дизайн вместо этого использует сдерживание и композицию - гораздо более предпочтительное решение. То есть, вы говорите, что элемент списка «IS-A» установлен, в то время как естественным состоянием является то, что флажок элемента «HAS-A» (и аналогично для переключателей).

Если вы вынуждены работать таким образом с помощью механизма виджетов, то неудивительно, что вам в конечном итоге понадобится множественное наследование, но это может добавить свои собственные сложности и, в любом случае, Подклассы приводят к сильному сцеплению и низкой гибкости, в то время как сдерживание и состав лучше в этом отношении. Я рекомендую прочитать классические шаблоны проектирования , которые очень хорошо объясняют эти проблемы.

В любом случае, если вы попали в ловушку такого рода дизайна, то да, можно , как вы говорите, написать:

ListItemBase(IWidgetContainer &container, CheckboxBP &blueprint) : 
        Checkbox(container, blueprint), IWidgetObject(this) {
 }

Однако это не означает, что конструктор базового класса Checkbox выполняется перед IWidgetObject: это зависит от порядка, в котором вы объявили свои базы (если вы объявите IWidgetObject в качестве первой базы, ее конструктор будет выполняться раньше другой) .

0 голосов
/ 19 сентября 2009

ОК, у меня есть идея

                  IWidgetObject
                        |
 ICheckbox        CheckboxBase     IRadioButton
  |  \               /  |  \           /    |
  |   `-------------´   |   `---------´     |
  |          |          |        |          |
  |    Checkbox         |    RadioButton    |
  |                     |                   |
  |               ListItemBase              |
   \                |      |               /
    `---------------´      `--------------´
           |                      |
     ListItemCheckbox        ListItemRadioButton

Что ты думаешь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...