工厂方法是创建对象时最常见的方法之一,我们在程序中创建一个对象往往会使用到new,在new的左边可以是一个抽象的基类,而new的右边则必须是一个具体的类,这种紧耦合的关系不是我们想要的。工厂方法就是用于解除这种耦合关系的办法!它是怎么做的了?用new无法避免的话,那就返回一个对象呗。
工厂方法的定义:是一种常见的对象创建型设计模式,此模式的核心思想是封装类中不变的部分(稳定的),提取其中个性化善变的部分(变化的)为独立类,通过依赖注入以达到解耦、复用以及方便后期维护拓展的目的。
实际应用中的例子,假设我们去买家电,家电品牌太多了,美的、格力、海尔等等选哪个呢?。
UML结构图如下:
下面我用伪码来表述上面的例子。
//首先看我们遇到的问题
int main()
{
//品牌的基类Brand
//具体的品牌,美的Midea
Brand *pB = new Midea();//看等号的右边,必须放一个具体的类
return 0;
}
//怎么解决这个问题呢?
//品牌基类
class Brand
{
public:
virtual ~Brand() {}
virtual void name()=0;//返回品牌的名字
};
//具体的品牌,我就不写那么详细了
class Midea {...};
class Gree {...};
class Haier {...};
//就用工厂方法来解决吧!
//千万注意这里的工厂不能这么写
//class BrandFactory
//{
//public:
// Brand *Create()
// {
// return new Midea();//这里还是要传具体类
// }
// //这种编译时就要确定的事怎么往后延迟到运行时?噔噔噔,那就加virtual呗
//};
//这样写才行
//工厂基类
class BrandFactory
{
public:
virtual ~BrandFactory() {}
virtual Brand *Create()=0;
};
//那么每个品牌都有一个具体的工厂
class MideaFactory : public BrandFactory
{
public:
virtual Brand *Create()
{
return new Midea();//这里可以传具体的类了
}
};
class GreeFactory : public BrandFactory{...};
class HaierFactory : public BrandFactory{...};
//应用
int main()
{
//应用的时候传进来一个BrandFactory的指针,比如这里可以传进来一个new MideaFactory();
BrandFactory *pFactory;
//多态的new,这里没有具体类了
Brand *pB = pFactory->Create();
return 0;
}
现在返回那张UML图我们再来看
结合到我们的例子和工厂方法的定义,其中稳定的部分就是我们的品牌类和工厂类。变化的是不同的品牌以及不同品牌对应的工厂。我们是通过虚函数的方法,把创建具体对象的工作延迟到子类中,较好地解决了这种紧耦合的关系。
最后,如果理解的有偏差,还请指出!