工厂方法模式
定义:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
通用源码模板:
定义抽象产品类:
class Product {
public:
//产品类的公共方法
void method1() {
//业务逻辑处理
}
//抽象方法
virtual void method2() = 0;
};
定义具体产品类:
class ConcreateProduct1 : public Product {
public:
virtual void method2() {
//业务逻辑处理
}
};
class ConcreateProduct2 : public Product {
public:
virtual void method2() {
//业务逻辑处理
}
};
定义抽象工厂类:
template <class AbsPro>
class Creator {
public:
virtual AbsPro* createProduct() = 0;
};
定义具体工厂类:
template <class AbsPro, class ConPro>
class ConcreteCreator : public Creator<AbsPro> {
public:
AbsPro* createProduct() {
return new ConPro();
}
};
场景调用类:
ConcreteCreator<Product, ConcreateProduct2> pc;
Product *p = pc.createProduct();
p->method2();
优点:
良好的封装性,代码结构清晰。根据产品的类名即可得到产品对象;
扩展性非常优秀。需要增加产品类时,只要适当地修改具体的工厂类或扩展一个工厂类就可以实现;
屏蔽产品类。调用者不需要关系产品类的实现,产品类的实现由工厂类完成;
典型的解耦框架。
使用场景:
工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要考虑复杂度;
需要灵活的,可扩展的框架时;
可以用在异构项目中;
使用在测试驱动开发的框架下;
扩展:
1 简单工厂模式
当一个模块只需要一个工厂类,即删除抽象工厂类,一个工厂固定的加工生产某一种抽象产品。
不符合开闭原则。
没有完美的模式,简单且符合需求即是完美。
2 升级为多个工厂类
为产品类增加适配其对应的工厂类来完成每个产品具体实现,比较合适产品类的初始化都不相同的情况下。
3 替代单例模式
4 延迟初始化
通过map将已经创建的产品类对象保留缓存,然后下一次如果需要获取对象,先判断map中是否存在,如果存在则直接取出返回,否则按需产生一个对象并放入到map容器中,方便下次调用。
示例代码
#include <iostream>
using namespace std;
class Human {
public:
virtual void getColor() = 0;
virtual void talk() = 0;
};
class Black : public Human {
public:
virtual void getColor() {
cout << "black" << endl;
}
virtual void talk() {
cout << "balabala black" << endl;
}
};
class Yellow : public Human {
public:
virtual void getColor() {
cout << "yellow" << endl;
}
virtual void talk() {
cout << "balabala yellow" << endl;
}
};
class White : public Human {
public:
virtual void getColor() {
cout << "white" << endl;
}
virtual void talk() {
cout << "balabala white" << endl;
}
};
template <class absHuman>
class AbstractHumanFactory {
public:
virtual absHuman* createHuman() = 0;
};
template <class absHuman, class conHuman>
class HumanFactory : public AbstractHumanFactory<absHuman> {
public:
absHuman* createHuman() {
cout << "create successful" << endl;
return new conHuman();
}
};
int main() {
HumanFactory<Human, Yellow> yf;
Human *y = yf.createHuman();
y->getColor();
y->talk();
return 0;
}