工厂方法的核心思想就是将具体的实例化推迟到子类。与简单工厂相比,它弥补了简单工厂的一些不足,如:简单工厂打破了开闭原则!工厂方法只负责创建对象,将原本的逻辑判断放到了client中。下面是用简单工厂实现的一个例子:
class IProduct
{
public:
virtual void Function() = 0;
};
class Product_A : public IProduct
{
public:
virtual void Function() override
{
}
};
class Product_B : public IProduct
{
public:
virtual void Function() override
{
}
};
class Creator
{
public:
static IProduct factory(int type)
{
if (/* ... */)
return new Product_A();
else if (/* ... */)
return new Product_B();
}
};
int main()
{
IProduct product = Creator.factory(type);
}
若要对Prodect进行拓展,比如添加一个产品Product_C,那么我们就要去修改Creator,这样就不符合开闭原则。下面是用工厂方法实现的代码示例:
class IProduct
{
public:
virtual void Function() = 0;
};
class Product_A : public IProduct
{
public:
virtual void Function() override
{
}
};
class Product_B : public IProduct
{
public:
virtual void Function() override
{
}
};
class ICreator
{
public:
virtual IProduct* create() = 0;
};
class Creator_A : public ICreator
{
public:
virtual IProduct* create() override
{
return new Product_A();
}
};
class Creator_B : public ICreator
{
public:
virtual IProduct* create() override
{
return new Product_B();
}
};
下面是客户端代码:
IProduct create(int type)
{
if (/* ... */)
return Creator_A::create();
else if (/* ... */)
return Creator_B::create();
}
int main()
{
IProduct product = create(type);
}
将变化部分交给了客户端,这样就符合开闭原则了。现在要想拓展功能,只需要写相应的类和工厂就行了,逻辑部分只有客户端会改变。
你可能会说,有必要那么麻烦,用工厂只封装一句new 语句。当然这里只是例子,在现实设计中,工厂中往往不止这一句调用。就算只有这一句也是值得的,它为以后的修改提供了很大的方便。假如客户端中要用到上千个产品,那就要有上千个new,现在要对产品的创建过程做一些改动……悲剧了,要改上千个地方。但如果我们用工厂来封装new,只需要修改两个具体工厂Create_A和Create_B就行了。