factory method 提供了一种延迟创建类的方式,使用这个方式可以在运行期由子类判断创建哪一个类的实例。其次,创建一个对象似乎是一个最简单的是object=new ClassName(),但面对大型软件或不同运行环境时就存在问题:
1、简单的创建方式造成硬编码,在不同的运行环境中就需要复杂的逻辑实例化不同的实例。
2、为了使用于不同的运行环境,通常我们需要定义抽象的接口,在不同的环境中实现不同的子类实例
效果:
根据不同的配置及上下文环境加载具有相同抽象类的不同实现实例,实现可配置,动态的创建
#include <iostream>
using namespace std;
namespace Occ{
/**
* 职业
*/
class Occupation {
public:
virtual void learn()=0;
virtual void write()=0;
virtual void read()=0;
};
class Student: public Occupation {
public:
void learn() {
cout << "学生学习..." << endl;
}
void write() {
cout << "学生写作..." << endl;
}
void read() {
cout << "学生读文章..." << endl;
}
};
class Teacher: public Occupation {
public:
void learn() {
cout << "老师学习..." << endl;
}
void write() {
cout << "老师写作..." << endl;
}
void read() {
cout << "老师读文章..." << endl;
}
};
}
namespace IFac{
class IFactory {
public:
virtual Occ::Occupation *createOccupation()=0;
};
class StudentFactory: public IFactory {
Occ::Occupation *createOccupation(){
return new Occ::Student();
}
};
class TeacherFactory: public IFactory {
Occ::Occupation *createOccupation(){
return new Occ::Teacher();
}
};
}
int main() {
//需要创建学生时
IFac::IFactory * ifctory =new IFac::StudentFactory();
Occ::Occupation * occupation=ifctory->createOccupation();
occupation->learn();
occupation->write();
occupation->read();
//需要创建老师时
IFac::IFactory * ifctory1 =new IFac::TeacherFactory();
Occ::Occupation * occupation1=ifctory1->createOccupation();
occupation1->learn();
occupation1->write();
occupation1->read();
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
Spring 通过工厂方法来配置bean
bean.xml
<bean id="ifctory " class="com.dpicadev.factoryMethod.IFactory ">
......
</bean>
<bean id="occupation" factory-bean="ifctory" factory-method="createOccupation">
.....
</bean>
<bean id="occupation1" factory-bean="ifctory" factory-method="createOccupation">
.....
</bean>
java:
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Occupation occupation= (Occupation ) ctx.getBean("occupation");
System.out.println(occupation->learn());
Occupation occupation1= (Occupation ) ctx.getBean("occupation1");
System.out.println(occupation1->learn());