在面向对象设计系统中我们经常遇到两个问题:
1)为了提高内聚和松耦合性,我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过基类的引用或者指针来指向子类的对象。这里很容易出现的一个问题是n多的子类继承自同一个抽象基类,所以我们不得不写出很多类似new **的代码。这里容易出现的两个问题是:
- 客机程序员必须知道实际子类的名称。
- 程序的扩展性和可维护行越来越差。
2)父类并不知道具体要实例化哪个子类。k_eckel先生举了这样一个例子:“假如我们在类A中要使用类B,类B是一个抽象父类,在A中并不知道要实例化B的那一个子类,但是在类A的子类D中是可以知道的,在类A中没有办法使用类似与new **的语句,因为根本不知道**是什么”,这个例子看得有点似懂非懂。
照着把代码敲了一便,说实话,对于书上的解释,没有全部理解。先贴上代码吧。
Factory.h
//Factory.h #ifndef _FACRORY_H_ #define _FACRORY_H_ #include "../Header Files/Product.h" class Product; class Factory { public: //如果不声明为虚析构函数, //则在使用delete p(p是基类的指针,指向子类),不会调用子类的析构函数,从而不会正常的释放所有的内存。 virtual ~Factory() = 0 ; virtual Product * CreateProduct() = 0 ; protected: Factory(); }; class ConcretFactory : public Factory { public: ~ConcretFactory(); ConcretFactory(); Product * CreateProduct(); protected: private: }; #endif
Factory.cpp
#include "../Header Files/Factory.h" #include <iostream> using namespace std; Factory::Factory() { cout<<"Base:Factory()"<<endl; } Factory::~Factory() { cout<<"Base:~Factory()"<<endl; } ConcretFactory::ConcretFactory() { cout<<"Derive:ConcretFactory()"<<endl; } ConcretFactory::~ConcretFactory() { cout<<"Derive:~ConcretFactory()"<<endl; } Product * ConcretFactory::CreateProduct() { return new ConcretProduct(); }
Product.h
//Product.h #ifndef _PRODUCT_H_ #define _PRODUCT_H_ class Product { public: //如果不声明为虚析构函数, //则在使用delete p(p是基类的指针,指向子类),不会调用子类的析构函数,从而不会正常的释放所有的内存。 virtual ~Product() = 0; virtual void print() = 0 ; protected: Product(); private: }; class ConcretProduct : public Product { public: ~ConcretProduct(); ConcretProduct(); void print(); }; #endif
Product.cpp
//Product.cpp #include "../Header Files/Product.h" #include <iostream> using namespace std; Product::Product() { cout<<"Base:Product()"<<endl; } Product::~Product() { cout<<"Base:~Product()"<<endl; } ConcretProduct::ConcretProduct() { cout<<"Derive:ConcretProduct()"<<endl; } ConcretProduct::~ConcretProduct() { cout<<"Derive:~ConcretProduct()"<<endl; } void ConcretProduct::print() { cout<<"Haha!..$20000000"<<endl; }
app.cpp
//app.cpp #include "Header Files/Product.h" #include "Header Files/Factory.h" int main() { Factory * factory = new ConcretFactory(); Product * p = factory->CreateProduct(); p->print(); delete p; delete factory; return 0; }
总的来说,工厂模式解决了两个问题:
对于大型的复杂系统,如果创建的对象非常的多,并且他们都继承自同一基类,那么工厂方法对创建对象过程的封装极大的提高了程序的可扩展性和封装性。
这一点很好理解。
第二个作用是将类的实例化延迟到子类。这个还真不是太理解,但真感觉他有那么一点用,暂且先记者吧,以后有了感悟再来补充。