使用Factory Pattern来实例化所有小部件是否合理?

时间:2011-07-21 08:39:18

标签: c++ user-interface factory-pattern

我正在研究使用工具模式在我的一个GUI工具包中实现样式和渲染,然后这个疯狂的想法让我感到震惊。为什么不对所有小部件使用工厂模式?

现在我正在考虑以下方式:

Widget label = Widget::create("label", "Hello, World");
Widget byebtn = Widget::create("button", "Good Bye!");

byebtn.onEvent("click", &goodByeHandler);

新的窗口小部件类型将使用Widget::register(std::string ref, factfunc(*fact))

等函数进行注册

您认为这种方法的优点和缺点是什么?

我敢打赌,使用std::map<std::string>几乎没有性能问题,因为它只在设置时使用。

是的,原谅我被JavaScript损坏以及我的C ++中的任何可能的语法错误,因为我使用该语言已经有一段时间了。


利弊总结

赞成

  • 从文件中动态加载新的小部件很容易
  • 小部件可以在运行时轻松替换(它也可以帮助进行单元测试)
  • 呼吁动态人物

缺点(和可能的解决方案)

  • 没有编译时检查(可以编写自己的构建时检查。JS / Python /命名它,也不是编译时检查;我相信开发人员没有它就做得很好)
  • 可能性能较差(不需要一直创建小部件。字符串映射不会一直用于 ,而是在创建小部件和注册事件处理程序时)
  • 向上/向下播放地狱(在需要时提供通常的课程实例化)
  • 可能使配置小部件变得更加困难(使小部件具有相同的选项)

我的GUI工具包处于早期阶段,在规划方面缺乏相当多。因为我不习惯制作GUI框架,所以我可能还有许多问题 /设计决定

现在我看不出小部件在他们的方法集中会有太大的不同,但这可能只是因为我还没有想到更高级的小部件。

感谢大家的投入!

3 个答案:

答案 0 :(得分:1)

我认为这不是很直观。我宁愿允许直接访问类。这里的问题是,为什么你想这样做。有技术原因吗?在包含小部件的“真实类”之上是否有更高的抽象层? 例如,您有外部API的纯虚拟类,然后是实现类? 但是如果不知道你的图书馆是如何建立的话,很难说这是否有用,但我自己并不是工厂的忠实粉丝,除非你真的需要它们。 如果你有这个更高的抽象层并想要那个工厂,那么看看irrlicht。它为API使用纯虚拟类,然后使用“实现类”。工厂根据所选的渲染器(directx,opengl,软件)选择正确的实现。 但他们并没有用字符串来识别想要的类。这是我在C ++中真的不会做的事情。 我的2美分。

答案 1 :(得分:1)

我会建议反对使用string作为关键字,并为每个子类型提升实际方法。

class Factory
{
public:
  std::unique_ptr<Label> createLabel(std::string const& v);
  std::unique_ptr<Button> createButton(std::string const& v, Action const* a);
};

这有几个好处:

  • 编译器检查过,你可以拼写错误的字符串,但你不能用错误的方法获得正在运行的程序
  • 更精确的返回类型,因此,不需要向上投射(及其所有困境)
  • 更精确的参数,并非所有元素都需要相同的参数集

通常,这样做是为了允许自定义。如果Factory是一个抽象接口,那么您可以使用多个实现(WindowsGTKMac),这些实现可以在不同方面创建它们。

然后,不是每种类型设置一个创建者功能,而是立即切换整个工厂。

注意:性能方面,虚拟函数比通过字符串键进行地图查找要快得多

答案 2 :(得分:1)

赞成

  • 从文件或其他外部源读取小部件很容易,并按名称创建小部件。

缺点

  • 将不正确的类型名称传递给Widget :: create会很容易,只会在运行时出错。
  • 如果没有向下转换,您将无法访问特定于窗口小部件的API - 即另外一个运行时错误源。
  • 找到创建特定类型小部件的所有地方可能并不容易。

为什么不通过常规构造函数和工厂创建小部件来充分利用这两个世界?