今天介绍另一个比较常用的设计模式:工厂模式。工厂模式是指通过声明一个工厂的接口,然后定义该接口的各个实现类来具体实现不同的工厂。这里不打算写这种一般的方式,而只是写一种简单的工厂模式:静态工厂模式。这种模式的扩展性不如一般工厂模式那么好,但对于我们一般的应用已经足够了(而且系统设计的太复杂也不是好事,呵呵),静态工厂在实际中还是很常用的。
值得说明的是这次没有像一般工厂模式那样采用普通的指针,而是采用之前介绍的shared_ptr,这是因为采用智能指针就不必担心工厂中创建的对象的释放问题,因为智能指针会帮你做好这一切,^_^
下面是示例代码,代码中每个类按照不同文件进行放置,这样也可以了解工厂模式的一个好处,减小使用者和创建的产品类之间的依赖关系,这会在后面说明。
FileName: product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class Product{
public:
virtual void myFunc()=0;
};
#endif
FileName: product_one.h
#ifndef _PRODUCT_ONE_H_
#define _PRODUCT_ONE_H_
#include "product.h"
class ProductOne:public Product{
public:
ProductOne();
~ProductOne();
void myFunc();
};
#endif
FileName: product_one.cpp
#include "product_one.h"
#include <iostream>
using namespace std;
ProductOne::ProductOne(){
cout<<"product one: i have been builded."<<endl;
}
ProductOne::~ProductOne(){
cout<<"Product one: i have been destroyed."<<endl;
}
void ProductOne::myFunc(){
cout<<"product one myFunc done!"<<endl;
}
FileName: product_two.h
#ifndef _PRODUCT_TWO_H_
#define _PRODUCT_TWO_H_
#include "product.h"
class ProductTwo:public Product{
public:
ProductTwo();
~ProductTwo();
void myFunc();
};
#endif
FileName: product_two.cpp
#include "product_two.h"
#include <iostream>
using namespace std;
ProductTwo::ProductTwo(){
cout<<"product two: i have been builded."<<endl;
}
ProductTwo::~ProductTwo(){
cout<<"Product two: i have been destroyed."<<endl;
}
void ProductTwo::myFunc(){
cout<<"product two myFunc done!"<<endl;
}
FileName: product_factory.h
#ifndef _PRODUCT_FACTORY_H_
#define _PRODUCT_FACTORY_H_
#include "product.h"
#include <tr1/memory>
#include <string>
class ProductFactory{
public:
static std::tr1::shared_ptr<Product> createProduct(std::string productDescript);
};
#endif
FileName: product_factory.cpp
#include "product_factory.h"
#include "product_one.h"
#include "product_two.h"
using namespace std;
using namespace std::tr1;
shared_ptr<Product> ProductFactory::createProduct(string productDescription){
if(productDescription=="one"){
shared_ptr<Product> productOne(new ProductOne());
return productOne;
//you can also do like below.
//return shared_ptr<Product> (new ProductOne());
}
else if(productDescription=="two"){
shared_ptr<Product> productTwo(new ProductTwo());
return productTwo;
//you can also do like below.
//return shared_ptr<Product> (new ProductTwo());
}
}
FileName: test_factory.cpp
#include "product.h"
#include "product_factory.h"
#include <string>
#include <iostream>
#include <tr1/memory>
using namespace std;
using namespace std::tr1;
int main(){
cout<<"test 1 start..."<<endl;
shared_ptr<Product> myProduct=ProductFactory::createProduct("one");
myProduct->myFunc();
cout<<endl<<"test 2 start..."<<endl;
myProduct=ProductFactory::createProduct("two");
myProduct->myFunc();
{
cout<<endl<<"test 3 start..."<<endl;
shared_ptr<Product> myProduct2=ProductFactory::createProduct("one");
myProduct2->myFunc();
}
cout<<"all test done."<<endl<<endl;;
}
编译然后运行:
# g++ -o test_factory test_factory.cpp product_one.cpp product_two.cpp product_factory.cpp # ./test_factory
运行结果如下:
test 1 start... product one: i have been builded. product one myFunc done! test 2 start... product two: i have been builded. Product one: i have been destroyed. product two myFunc done! test 3 start... product one: i have been builded. product one myFunc done! Product one: i have been destroyed. all test done. Product two: i have been destroyed.
从上面结果可以看出通过使用工厂模式,可以使实例对象的生成由工厂来完成,减小使用者test_factory与实例产品product_one、product_two的依赖,这样也有利于后续程序的维护,即使product_one后来取消了,改动的代码也不会很大。大家看下test_factory.cpp的包含文件可以看出使用者不需要知道实际的产品子类(不直接知道),减小了编译的依赖。
通过采用shared_ptr智能指针,可以避免使用者忘记释放掉new产生的实例类。这也使得代码更加安全,不容易造成内存泄露,也更容易编写异常安全或异常中立的代码。
[题外话]也可以看出shared_ptr对于继承派生有很好的支持,^_^
五月 20th, 2010 at 7:38 下午
牛逼
[回复]
flyingfish 回复:
五月 23rd, 2010 at 11:18 下午
还好了,也只是一些基本知识而已,多谢捧场, 呵呵
[回复]
五月 28th, 2010 at 4:29 下午
谢谢博主的文章
[回复]