当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 深入浅出《设计模式》之工厂模式(C++)

深入浅出《设计模式》之工厂模式(C++)

2019年07月19日  | 移动技术网IT编程  | 我要评论

前言

模式介绍

在之前简单工厂模式中,我们介绍了简单工厂模式的缺陷是违背了开放-封闭原则。如果在面馆中添加了烤海参,那将会修改waiter工厂类。违背了类内封闭原则。

还以面馆为例,现在两种面,用一个服务员来卖就可以,如果这个服务员不干了,后面卖面的厨师需要兼职顶替服务员,但是厨师又不能离开灶台,就将模式改成了窗口排队式,一队海参炒面,另一队辣根汤面。每个窗口分别有一个厨师放饭,一个会做海参炒面,另一个会做辣根汤面。老板觉得这种模式挺好,万一来了一个会做烤海参的,就只需要开一个烤海参的窗口就好了,不需要重新要服务员学习,因为烤海参的就会卖。这就变成了工厂模式。

uml类图

这里涉及到2种类①我,客户端,排队买饭。②做饭厨师类,工厂类,为我生成饭。③菜品类,生成菜品类。具体关系如下uml类图:

代码实例

下面是noodle类,是为工厂类使用的,继承他就可以扩展noodle类别:

#ifndef noodle_h
#define noodle_h

class noodle
{
public:
    noodle() {}
    ~noodle() {}

   virtual void eating() = 0;
};

#endif // noodle_h

下面是海参炒面类,继承了noodle,实现eating方法,吃海参炒面:

#ifndef haishennoodle_h
#define haishennoodle_h

#include "noodle.h"

class haishennoodle : public noodle
{
public:
    haishennoodle();
    ~haishennoodle();

    virtual void eating();
};

#endif // haishennoodle_h
#include <iostream>
#include "haishennoodle.h"

haishennoodle::haishennoodle()
{

}

haishennoodle::~haishennoodle()
{

}

void haishennoodle::eating()
{
    std::cout << "我是海参炒面,里面没有海参哦!!吃的时候注意!" << std::endl;
}

下面是辣根汤面,继承了noodle,实现eating方法,吃辣根汤面:

#ifndef lagennoodle_h
#define lagennoodle_h

#include "noodle.h"

class lagennoodle : public noodle
{
public:
    lagennoodle();
    ~lagennoodle();

    virtual void eating();
};

#endif // lagennoodle_h
#include <iostream>
#include "lagennoodle.h"

lagennoodle::lagennoodle()
{

}

lagennoodle::~lagennoodle()
{

}

void lagennoodle::eating()
{
    std::cout << "我是辣根汤面,吃完呛的哼啊!!!" << std::endl;
}

下面是waiter工厂的基类。所有工厂都继承这个类:

#ifndef waiter_h
#define waiter_h

class noodle;
class waiter
{
public:
    waiter() {}
    ~waiter() {}

    virtual noodle *createnoodle() = 0;
};

#endif // waiter_h

下面是海参厨师(工厂1),海参厨师只管做海参炒面,重写了createnoodle方法:

#ifndef haishen_h
#define haishen_h

#include "waiter.h"

class noodle;
class haishen : public waiter
{
public:
    haishen();
    ~haishen();

    virtual noodle *createnoodle();
};

#endif // haishen_h
#include <iostream>
#include "haishen.h"
#include "haishennoodle.h"

haishen::haishen()
{

}

haishen::~haishen()
{

}

noodle *haishen::createnoodle()
{
    std::cout << "面是我炒得,我的名字叫海参!!!" << std::endl;
    return new haishennoodle();
}

下面是辣根厨师(工厂1),辣根厨师只管做辣根汤面,重写了createnoodle方法:

#ifndef lagen_h
#define lagen_h

#include "waiter.h"

class lagen : public waiter
{
public:
    lagen();
    ~lagen();

    virtual noodle *createnoodle();
};

#endif // lagen_h
#include <iostream>
#include "lagen.h"
#include "lagennoodle.h"

lagen::lagen()
{

}

lagen::~lagen()
{

}

noodle *lagen::createnoodle()
{
    std::cout << "吃辣根汤面,你不觉得呛得哼吗??" << std::endl;
    return new lagennoodle();
}

下面是客户端,客户端通过类别,使用相应的工厂类建立相应的实例:

#include <iostream>
#include <string.h>

#include "haishen.h"
#include "lagen.h"
#include "noodle.h"

using namespace std;

char *product_list[] = {
    "haishen-noodle",
    "lagen-noodle",
    null
};

int main()
{
    char *p = null;
    char *pd = "haishen-noodle";
    int i = 0;

    waiter *w = null;
    noodle *n = null;

    for(p = product_list[i]; p != null; i++, p = product_list[i]) {
        if(strncmp(pd, p, strlen(pd)) == 0) {
           if(i == 0) {
               w = new haishen();
           } else if(i == 1) {
               w = new lagen();
           } else {
               cout << "对不起,请您排在队内!!!" << std::endl;
               break;
           }

        }
    }

    if(w) n = w->createnoodle();
    if(n) n->eating();

    if(w) {
        delete w; w = null;
    }

    if(n) {
        delete n; n = null;
    }
    return 0;
}

下面是cmakelist.txt文件,帮助生成makefile:

cmake_minimum_required(version 2.8)

project(noodle-factory)
set(src_list main.cpp noodle.h waiter.h haishen.h haishen.cpp haishennoodle.h haishennoodle.cpp
    lagennoodle.h lagennoodle.cpp lagen.h lagen.cpp)
add_executable(${project_name} ${src_list})

编译运行结果

代码下载链接是:https://github.com/erguangqiang/freesir_headfirst/blob/master/noodle-factory.tar.gz
使用cmake生成makefile,并编译出可执行程序noodle。运行结果如下:

erguangqiang@elab$./noodle-factory
面是我炒得,我的名字叫海参!!!
我是海参炒面,里面没有海参哦!!吃的时候注意!

结束

工厂模式解决了简单工厂违背了的开放-封闭原则。虽然累的结构变的复杂了,但是对于扩展性得到了很大的提高。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网