C++静态工厂模式(采用shared_ptr)

C/C++ 3 Comments »

    今天介绍另一个比较常用的设计模式:工厂模式。工厂模式是指通过声明一个工厂的接口,然后定义该接口的各个实现类来具体实现不同的工厂。这里不打算写这种一般的方式,而只是写一种简单的工厂模式:静态工厂模式。这种模式的扩展性不如一般工厂模式那么好,但对于我们一般的应用已经足够了(而且系统设计的太复杂也不是好事,呵呵),静态工厂在实际中还是很常用的。

    值得说明的是这次没有像一般工厂模式那样采用普通的指针,而是采用之前介绍的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对于继承派生有很好的支持,^_^

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS 登录