我不知道这是否有一个正式的名称,但我一直在玩我喜欢称之为“自我工厂”模式的东西。基本上,当抽象基类充当其自身的工厂时。让我解释一下:
我的系统中有Foo对象和Bar对象,它们通过接口FooInterface和BarInterface使用。我需要给我的客户提供正确的Foo和Bar类型。在编译时决定创建哪个具体的Foo对象。例如,如果你在win32上编译,你只想创建Win32Foo对象,如果你在OSX上编译,你只想创建OSXFoo对象,依此类推。但是,要创建哪个混凝土Bar对象的决定是在运行时根据键字符串做出的。
现在,我的问题是关于实现这个计划的最佳方法。我想出的一种方法是使用常规工厂:
shared_ptr<FooInterface> foo = FooFactory::create();
shared_ptr<BarInterface> happyBar = BarFactory::create("Happy");
shared_ptr<BarInterface> sadBar = BarFactory::create("Sad");另一种方法是使用我所说的“自我工厂”:
shared_ptr<FooInterface> foo = FooInterface::create();
shared_ptr<BarInterface> happyBar = BarInterface::create("Happy");
shared_ptr<BarInterface> sadBar = BarInterface::create("Sad");无论是从可用性角度还是从架构角度来看,每种方法的优缺点是什么?
发布于 2009-06-24 22:04:05
工厂有两种常见用途:
1)根据参数和/或全局状态(如配置),在运行时决定动态多态类型。您的模式做到了这一点。
2)依赖注入:不是使用静态函数来创建对象,而是使用工厂对象,以便调用者可以通过传入他们想要的任何工厂来配置返回的对象类型。这两种模式都不提供这一点。此外,您的第二个模式甚至不允许静态依赖注入(通过具有接受工厂类作为模板参数的模板函数),因为接口和工厂是相同的。
因此,您的模式(和常规工厂)的一个缺点是并不真正支持依赖注入。要获取一个FooInterface对象,需要调用且只有一个函数,那就是FooInterface::create()。我不会争论为什么依赖注入是有用的,只是指出,如果你以这种方式构建,你就不能使用它。
发布于 2009-06-24 22:12:42
我会做一些改进:
shared_ptr<FooInterface> foo = Factory<FooInterface>::create();
shared_ptr<BarInterface> happyBar = Factory<BarInterface>::create("Happy");
shared_ptr<BarInterface> sadBar = Factory<BarInterface>::create("Sad");你会声明:
template <class I>
struct Factory { };然后,对于每个需要工厂的接口,您将执行以下操作:
template <>
struct Factory<FooInterface>
{
static FooInterface create();
};这允许您将工厂实现与接口声明分开,但仍然使用类型系统在编译时绑定它们。
发布于 2009-06-24 22:01:08
通常,工厂负责创建整个类层次结构的对象。因此,在您的示例中,您将拥有Win32Factory、OSXFactory等。这样做的一个好处是,在工厂创建期间,您只需选择一次特定的实现( win32/unix/ etc ),但如果您使用类接口,则必须始终提供操作系统信息。
如果只有两个类(Foo和Bar),我不确定是否值得为它们创建工厂,而不是仅仅使用接口的create方法。
哦,当一个接口有一个用于创建其类型的对象的方法时,它被称为factory method pattern。
https://stackoverflow.com/questions/1041218
复制相似问题