思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
抽象工厂模式的类图:
AbstractFactory-声明一个创建抽象产品对象的操作接口。
ConcreteFactory-实现创建具体产品对象的操作。
AbstractProduct-声明一类产品对象的接口。
Product-实现AbstractProduct接口的,被相应具体工厂创建的产品对象。
Client-仅使用AbstractFactory和AbstractProduct类声明的接口。
代码实现:
抽象和具体工厂的类放在一起,这样写的好处有很多,最后解释。
/*学院的抽象工厂类*/ //相互依赖关系很强的类放在一起写的 class DepartmentFactory{ public: DepartmentFactory(){} ~DepartmentFactory(){} //创建教学办和软件工程系两个对象的纯虚函数 virtual Office* CreateOffice()=0; //虚函数的写法 virtual Leader* CreateLeader()=0; //抽象工厂的作用,统一好多产品对象的创建 }; /*建筑学院的抽象工厂类*/ class ConstructDepartmentFactory:public DepartmentFactory{ public: ConstructDepartmentFactory(){} ~ConstructDepartmentFactory(){} //ConstructOffice和ConstructLeader是相关的对象,无需具体的产品类来创建这个对象。 Office* CreateOffice() { return new ConstructOffice(); } Leader* CreateLeader() { return new ConstructLeader(); } }; /*计算机学院的工厂类*/ class CSDepartmentFactory:public DepartmentFactory{ public: CSDepartmentFactory(){} ~CSDepartmentFactory(){} //具体工厂的作用是用来创建对象的,产品的创建由具体的产品类来完成。 //具体产品类可能继承自抽象产品类 Office* CreateOffice() //写错了,是CreateOffice { return new CSOffice(); } Leader* CreateLeader() { return new CSLeader(); } };
产品线和具体的产品族的类代码放在一起:
//学院办公室抽象类 class Office{ public: Office(){} ~Office(){} virtual void CreateOffice()=0; //虚函数的写法 }; //学院领导抽象类 class Leader{ public: Leader(){} ~Leader(){} virtual void CreateLeader()=0; }; //计算机学院办公室类 class CSOffice:public Office { public: CSOffice(){} ~CSOffice(){} void CreateOffice() { cout<<"CSOffice"<<endl; } }; class ConstructOffice:public Office{ public: ConstructOffice(){} ~ConstructOffice(){} void CreateOffice() { cout<<"ConstructOffice"<<endl; } }; class CSLeader:public Leader{ public: CSLeader(){} ~CSLeader(){} void CreateLeader() { cout<<"CSLeader"<<endl; } };
测试的代码:
CSDepartmentFactory *df=new CSDepartmentFactory; df->CreateOffice()->CreateOffice(); //只是创建了对象,还需要继续调用 df->CreateLeader()->CreateLeader(); ConstructDepartmentFactory *dy=new ConstructDepartmentFactory; dy->CreateOffice()->CreateOffice(); dy->CreateLeader()->CreateLeader();
测试结果的图片:
总结经验和引出的问题:
1、依赖关系很紧密的类定义放在一起,这样可以避免复杂的头文件循环依赖问题。
2、C++工程只编译源文件,需要的时候才编译头文件。
3、虚函数和纯虚函数的写法不一样。
4、抽象工厂模式是创建对象的模式,最后的调用还需要用指针来调用相关的函数。
引出的C++的问题:
1、C++命名空间。
3、C++单元测试。
4、C++宏定义的用法。
5、C++网络编程。
6、C++多线程问题。
7、C++虚函数和纯虚函数的用法,这个比较有料。
8、C++标准库和Boost库。
9、QT
这些问题会在后续的博文中给出答案。