C++设计模式之工厂模式大集合

意图:在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

关键代码:创建过程在其子类执行。

应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

工厂模式一般分为三种:简单工厂模式、工厂方法模式、抽象工厂模式

一、简单工厂模式:

  简单工厂模式,工厂类是创建产品的,它决定创建哪一种产品,就像领导决定采用那种技术方案样。举个例子,现在有宝马车和奔驰车两种车需要生产,但是只有一个工厂,且只能在同一时间生产一种车,这时就有工厂决定生产那种车了。例子虽然不是十分恰当,但是会其意即可。我们直接看UML类图和代码吧。

看代码就一目了然了:

#include <iostream>
using namespace std;

enum CarType{BENZ, BMW};

class Car//车类
{
public:
    virtual void createdCar(void) = 0;
};

class BenzCar : public Car //奔驰车
{
public:
    BenzCar()
    {
        cout<<"Benz::Benz()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BenzCar::createdCar()"<<endl;
    }
    ~BenzCar()
    {

    }
};

class BmwCar : public Car //宝马车
{
public:
    BmwCar()
    {
        cout<<"Bmw::Bmw()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BmwCar::createdCar()"<<endl;
    }
};


class CarFactory //车厂
{
public:
    Car* createSpecificCar(CarType type)
    {
        switch(type)
        {
        case BENZ://生产奔驰车
            return (new BenzCar());
            break;
        case BMW://生辰宝马车
            return (new BmwCar());
            break;
        default:
            return NULL;
            break;
        }
    }
};

int main(int argc, char** argv)
{
    CarFactory carfac;
    Car* specificCarA = carfac.createSpecificCar(BENZ);//看到网上众多示例在new后没有delete,感觉不是特别严谨
    Car* specificCarB = carfac.createSpecificCar(BMW);

    delete specificCarA; delete specificCarB;
    
    return 0;
}

 输出结果如下:

简单工厂模式在每次增加新的车型时,需要修改工厂类,这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。

二、工厂方法模式:

  工厂方法模式:不再只由一个工厂类决定那一个产品类应当被实例化,这个决定权被交给子类去做。当有新的产品(新型汽车)产生时,只要按照抽象产品角色、抽象工厂角色提供的方法来生成即可(新车型可以用一个新类继承创建产品即可),那么就可以被客户使用,而不必去修改任何已有的代 码。可以看出工厂角色的结构也是符合开闭原则。如下面UML类图 

 

 

#include <iostream>
using namespace std;

class Car//车类
{
public:
    virtual void createdCar(void) = 0;
};

class BenzCar : public Car //奔驰车
{
public:
    BenzCar()
    {
        cout<<"Benz::Benz()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BenzCar::createdCar()"<<endl;
    }
    ~BenzCar()
    {

    }
};

class BmwCar : public Car //宝马车
{
public:
    BmwCar()
    {
        cout<<"Bmw::Bmw()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BmwCar::createdCar()"<<endl;
    }
};


class Factory//车厂
{
public:
    virtual Car* createSpecificCar(void) = 0;
};

class BenzFactory : public Factory//奔驰车厂
{
public:
    virtual Car* createSpecificCar(void)
    {
        return (new BenzCar());
    }
};

class BmwFactory : public Factory//宝马车厂
{
public:
    virtual Car* createSpecificCar(void)
    {
        return (new BmwCar());
    }
};


int main(int argc, char** argv)
{
    Factory* factory = new BenzFactory();
    Car* specificCarA = factory->createSpecificCar();
    factory = new BmwFactory();
    Car* specificCarB = factory->createSpecificCar();
    
    delete factory; delete specificCarA; delete specificCarB;
    
    return 0;
}

 

三、抽象工厂:

  在上面的工厂方法模式基础上,有需要生产高配版的奔驰和宝马,那工厂方法模式就有点鞭长莫及了,这就又有抽象工厂模式,UML类图如下:

 

#include <iostream>
using namespace std;

class Car//车类
{
public:
    virtual void createdCar(void) = 0;
};

class BenzCar : public Car //奔驰车
{
public:
    BenzCar()
    {
        cout<<"Benz::Benz()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BenzCar::createdCar()"<<endl;
    }
    ~BenzCar()
    {

    }
};

class BmwCar : public Car //宝马车
{
public:
    BmwCar()
    {
        cout<<"Bmw::Bmw()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"BmwCar::createdCar()"<<endl;
    }
};

class HighCar //高配版车型
{
public:
    virtual void createdCar(void) = 0;
};

class HighBenzCar : public HighCar //高配奔驰车
{
public:
    HighBenzCar()
    {
        cout<<"HighBenzCarBenz::Benz()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"HighBenzCar::createdCar()"<<endl;
    }
};

class HighBmwCar : public HighCar //高配宝马车
{
public:
    HighBmwCar()
    {
        cout<<"HighBmwCar::Bmw()"<<endl;
    }
    virtual void createdCar(void)
    {
        cout<<"HighBmwCar::createdCar()"<<endl;
    }
};

class Factory//车厂
{
public:
    virtual Car* createSpecificCar(void) = 0;
    virtual HighCar* createdSpecificHighCar(void) = 0;
};

class BenzFactory : public Factory//奔驰车厂
{
public:
    virtual Car* createSpecificCar(void)
    {
        return (new BenzCar());
    }

    virtual HighCar* createdSpecificHighCar(void)
    {
        return (new HighBenzCar());
    }
};

class BmwFactory : public Factory//宝马车厂
{
public:
    virtual Car* createSpecificCar(void)
    {
        return (new BmwCar());
    }
    virtual HighCar* createdSpecificHighCar(void)
    {
        return (new HighBmwCar());
    }
};


int main(int argc, char** argv)
{
    Factory* factory = new BenzFactory();
    Car* specificCar = factory->createSpecificCar();
    HighCar* spcificHighCar = factory->createdSpecificHighCar();
    
    delete factory; delete specificCar; delete spcificHighCar;
    
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值