23种设计模式之一(创建型模式)Factory模式

一、简介

        Factory 模式是为了解决两类问题:

1、Factory封装对象的创建

        第一种问题是为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口这样我们可以通过声明一个指向基类的指针来指向实际的子类实现达到了多态的目的这里很容易出现的问题是 n 多的Product的子类继承自抽象基类Product,不得不在每次要用到子类的地方就编写诸如 new ConcreteProduct的代码,带来的麻烦即是:(1)客户程序员必须知道实际子类的名称如ConcreteProduct1、ConcreteProduct2等,当系统复杂后,命名将是一个很不好处理的问题(2)程序的扩展性和维护变得越来越困难,必须保存每一个对象的指针。

         为了解决上述问题,我们经常就是使用Factory模式声明一个创建对象的接口,并封装了对象的创建过程。Factory 这里类似于一个真正意义上的Factory工厂(生产对象)。如下图所示:


在工厂中即可使用:

Product *ConcreteFactory::CreateProduct(int number)
{
   switch(number) {
       case 1:
          return new ConcreteProduct1(); 
       break;
       case 2:
           return new ConcreteProduct2(); 
       break;
       case 3:
           return new ConcreteProduct3(); 
       break;
   }      
}

2、Factory具体化类延迟到子类

        第二种问题是在父类Factory中并不知道具体要实例化哪一个具体的子类,比如Factory类中要使用类Product(抽象父类),但Factory中并不知道具体要实例化ConcreteProduct1还是ConcreteProduct3,但在Factory类的子类ConcreteFactory中是可以知道的,故Factory具体化类的工作延迟到了子类ConcreteFactory中,使用newConcreteProduct1或new ConcreteProduct3。


        该设计与第一种的区别在于并不是只是为了封装类Product的子类对象的创建,而是要把对象的创建延迟到子类ConcreteFactory中实现,因为有时只有子类中可以决定到底实例化哪一个类。

Product *ConcreteFactory::CreateProduct()  //创建操作
{
    if (_flag == 1) {
        return new ConcreteProduct1();     //子类中决定要实例化哪一个类
    }
    else if (_flag == 3){
        return new ConcreteProduct3();
    }
}

二、详解

1、代码实现

(仅实现第二种功能代码,完整代码已上传到csdn)

(1)代码product.h:

#ifndef _PRODUCT_H_
#define _PRODUCT_H_

class Product
{
    public:
        virtual ~Product() = 0;
    protected:
        Product();
    private:
};

class ConcreteProduct1 : public Product
{
    public:
        ~ConcreteProduct1();
        ConcreteProduct1();
    protected:  
    private: 
};
class ConcreteProduct3 : public Product
{
    public:
        ~ConcreteProduct3();
        ConcreteProduct3();
    protected:  
    private: 
};
#endif
(2)代码product.cpp:

#include "product.h"
#include<iostream>
using namespace std;

Product::Product()
{
    cout<<"Product constructor"<<endl;
}

Product::~Product()
{
    cout<<"Product destructor"<<endl;
}

ConcreteProduct1::ConcreteProduct1()
{
    cout<<"ConcreteProduct1 constructor"<<endl;
}

ConcreteProduct1::~ConcreteProduct1()
{
    cout<<"ConcreteProduct1 destructor"<<endl;
}

ConcreteProduct3::ConcreteProduct3()
{
    cout<<"ConcreteProduct3 constructor"<<endl;
}

ConcreteProduct3::~ConcreteProduct3()
{
    cout<<"ConcreteProduct3 destructor"<<endl;
}
(3)代码factory.h:

#ifndef _FACTORY_H_
#define _FACTORY_H_

class Product;
class Factory
{
    public:
        virtual ~Factory() = 0;
        virtual Product *CreateProduct() = 0;
        void setFactoryMethod(int flag);
    protected:
        Factory();
        int _flag;
    private:
};

class ConcreteFactory : public Factory
{
    public:
        ~ConcreteFactory();
        ConcreteFactory();
        virtual Product *CreateProduct();
    protected:
    private:
};

#endif
(4)代码factory.cpp:
#include "product.h"
#include "factory.h"
#include <iostream>
using namespace std;
Factory::Factory()
    :_flag(0)
{
}

Factory::~Factory()
{
}

void Factory::setFactoryMethod(int flag)
{
    _flag = flag;
}

ConcreteFactory::ConcreteFactory()
{
    cout<<"---ConcreteFactory constructor"<<endl;
}

ConcreteFactory::~ConcreteFactory()
{
    cout<<"---ConcreteFactory destructor"<<endl;
}

Product *ConcreteFactory::CreateProduct()  //创建操作
{
    if (_flag == 1) {
        return new ConcreteProduct1();     //子类中决定要实例化哪一个类
    }
    else if (_flag == 3){
        return new ConcreteProduct3();
    }
}
(5)代码main.cpp:
#include "factory.h"
#include "product.h"
#include <iostream>
using namespace std;

int main()
{
    Factory *fac = new ConcreteFactory();

    //ConcreteFactory延时通过决定参数决定到底创建具体哪一个Product的子类
    fac->setFactoryMethod(3);
    Product *pro = fac->CreateProduct();
    
    if (pro) {
        delete pro;
        pro = NULL;
    }
    if (fac) {
        delete fac;
        fac = NULL;
    }
    return 0;
}
(6)makefile文件:
CFLAGS = -g
DEFINED = #-D _VERSION
LIBS = 
CC = g++
INCLUDES = -I./
OBJS= main.o factory.o product.o
TARGET= main
all:$(TARGET)

$(TARGET):$(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS)

.SUFFIXES:.o .h
.SUFFIXES:.cpp .o
.cpp.o:
	$(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<

ok:
	./$(TARGET)
clean:
	rm -f $(OBJS) $(TARGET) core *.log

2、运行结果

(centos6.3系统中运行结果:)

三、总结

(1)Factory 模式在实际开发中应用非常广泛,面向对象的系统经常面临着对象创建问题:要创建的类实在是太多了,而 Factory 提供的创建对象的接口封装(第一个功能),以及其将类的实例化推迟到子类(第二个功能)都部分地解决了实际问题。

(2)在实现中通过参数化工厂方法fac->setFactoryMethod(3)决定是创建具体哪一个具体的Product的子类是非常有用的。

(3)Factory 模式带来的问题:如果为每一个具体的ConcreteProduct类的实例化提供一个函数体,那么我们可能不得不在系统中添加了一个方法来处理这个新建的 ConcreteProduct,这样 Factory 的接口永远就不肯能封闭(Close)。当然我们可以通过创建一个 Factory 的子类来通过多态实现这一点但是这也是以新建一个类作为代价的。虽然Factory 模式对于对象的创建给予开发人员提供了很好的实现策略,但是Factory 模式仅仅局限于一类类(就是说 Product 是一类,有一个共同的基类),如果我们要为不同类的类提供一个对象创建的接口,那就要用 AbstractFactory 了。

(4)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8401713)。  

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值