与GUI的复合模式

时间:2014-04-15 17:44:28

标签: design-patterns user-interface

我在为游戏设计GUI时遇到问题。到目前为止,我已经得出结论,复合模式将允许我将所有 UIComponents 视为相同,无论一个是 UIButton ,另一个是 UIMenu 。这是UIComponent接口:

class UIComponent {
   virtual void Init() = 0;
   virtual void Draw() = 0;
}

我的每个实现类( UIFrame,UIButton,UITextBox,UIMenu,... )现在可以相互协作。此设计中的复合类是UIMenu类,因为它 IS A UIComponent和 HAS A UIComponent。

class UIMenu : public UIComponent {
   private:
      vector<UIComponent*> children_;

   public:
      virtual void Init() {
         // Initialize any data
      };

      virtual void Draw() {
         // Delegate drawing to each child
         for each(UIComponent* component in children_) {
            component->Draw();
         }
      };

      void AddComponent(UIComponent* child) {...};
      void RemoveComponent(UIComponent* child) {...};
}

因为我想支持所有 UIComponents 中的拖放功能,所以每个组件都需要位置,尺寸,比例,父级和图层( ComponentData )。为此,我需要将它们分别添加到每个实现类中,对我来说,这似乎是错误的方法。

class UIFrame : public UIComponent {
   private:
      string imgID_;

      int layer_;
      double relX_, relY_;
      double width_, height_;
      double scaleX_, scaleY_;

      UIComponent* parent_;
   public:
      virtual void Init() {...}
      virtual void Draw() {...}

      ...
};

这是否已经破坏了复合模式,因为我现在通过聚合使每个组件实现成为复合?如果我希望我的UIButton具有相同的定位,转换和缩放功能,我需要从UIFrame继承或将数据成员复制到UIButton。

有没有更好的方法来创建 UIComponent 接口的实现?例如,我们可以让UIFrame成为所有需要移动能力的组件的基类,而不是UIButton,UITextBox,UILabel等。现在,像UIButton这样的组件将成为UIFrame的子组件,以便重用ComponentData。

在UIComponent接口中放置涉及定位,转换和缩放的方法会更好吗?这将强制每个组件都知道如何在屏幕上操作自己。但是,我仍然留下了问题,&#34;我在哪里放置ComponentData(位置,尺寸,比例)?&#34;

我非常喜欢复合模式的概念以及以原子方式处理Tree结构的Leaf和Branch节点的能力。它还允许我使用装饰器模式来创建UIMenu对象的多次迭代,这样我就可以通过更改每个菜单所具有的UIComponent来获得InventoryMenu,CharacterInfoMenu,OptionsMenu等。

1 个答案:

答案 0 :(得分:0)

您可以使用支持拖放所需的数据项和方法创建超类UIDraggable,每个可拖动元素都可以继承它。 UIDraggable可以继承UIComponent