Factory Method 工厂方法

1. 需要解决的问题

代码1 : FileSplitter1.cpp

class ISplitter
{ //抽象基类
public:
    virtual void split() = 0;
    virtual ~ISplitter() {}
};

class BinarySplitter : public ISplitter
{
};

class TxtSplitter : public ISplitter
{
};

class PictureSplitter : public ISplitter
{
};

class VideoSplitter : public ISplitter
{
};

代码2: MainForm.cpp(这个是客户端)

#include "FileSplitter1.cpp"
class MainForm : public Form
{
    TextBox *txtFilePath;
    TextBox *txtFileNumber;
    ProgressBar *progressBar;

public:
    void Button1_Click()
    {

        //面向接口原则
        //依赖倒置原则
        ISplitter *splitter =
            new BinarySplitter(); //依赖具体类, 现在想要把这个依赖去除

        splitter->split();
    }
};

问题缘由:
在代码:

ISplitter *splitter =
            new BinarySplitter(); //依赖具体类, 现在想要把这个依赖去除

中, 客户端的需要创建BinarySplitter(), 需要依赖这个类, 我们现在不想要依赖这个类.
也就是说, 当我们把左边的变成了抽象之后, 右边的我们也想变抽像.
这种是接口抽象之后的第一步工作.
具体见下图("对象创建"模式的作用):
在这里插入图片描述

2. 抽丝剥茧走向工厂模式

2.1 想一个方法, 不使用new来创建对象

  • 直接实例化: BinarySplitter b, 不行, 也是依赖
  • ISplitter i, 也不行
  • 写一个方法, 返回新的对象

2.2 写一个方法, 返回新的对象

  1. 新建一个工厂类, 里面有一个方法:

    class SplitterFactory{
    public:
        ISplitter* CreateSplitter(){
            return new BinarySplitter();
        }
    };
    
  2. 客户端里的代码变成:

    SplitterFactory factory;
        ISiplitter* splitter = factory.CreateSplitter();
    

上面1, 2的做法其实也是一样的, 因为工厂的创建方法需要依赖BinarySplitter, 因此客户端里的创建方法也是间接需要依赖BinarySplitter的.

那我们怎么弄才能变成运行时依赖呢? 通过虚函数实现运行时绑定:
我们把代码改为:

class SplitterFactory{
public:
    virtual ISplitter* CreateSplitter() = 0;
    virtual ~SplitterFactory(){}
};

//客户端:
SplitterFactory* factory;//因为是抽象的, 因此只能用指针
ISplitter* splitter = factory->CreateSplitter();

3. 最后的代码

现在的代码是: MainForm类和工厂类都很稳定, 如果需要增加其他功能, 新增工厂子类和功能类即可, 不需要修改. 符合开-闭原则

//file: main_form.cpp
#include "file_splitter.cpp"

//MainForm已经不依赖别的了: 很稳定了
//里面有m_factory和splitter, 都是抽象的
class MainForm{
    SplitterFactory* m_factory;
public:
    MainForm(SplitterFactory* factory): m_factory(factory){}

    void execute(){
        ISplitter* splitter = m_factory->CreateSplitter(); //用工厂创建分割器, 具体是什么要看传经来的factory
        splitter->split(); //根据上面不同的工厂返回不同的分割器
    }
};

int main(int argc, char const *argv[])
{
    //我想创建一个文本分割器
    TxtSplitterFactory* text_factory = new TxtSplitterFactory;
    MainForm m_f(text_factory);
    m_f.execute();
    delete text_factory;
    return 0;
}



//file: file_splitter.cpp
#include <iostream>
using namespace std;
class ISplitter
{ //抽象基类
public:
    virtual void split() = 0;
    virtual ~ISplitter() {}
};

class SplitterFactory
{
public:
    virtual ISplitter *CreateSplitter() = 0;
    virtual ~SplitterFactory() {}
};

//具体类
class BinarySplitter : public ISplitter
{
public:
    void split()
    {
        cout << "binary" << endl;
    }
};

class TxtSplitter : public ISplitter
{
public:
    void split()
    {
        cout << "text" << endl;
    }
};

//具体工厂
class BinarySplitterFactory : public SplitterFactory
{
public:
    virtual ISplitter *CreateSplitter()
    {
        return new BinarySplitter;
    }
};

class TxtSplitterFactory : public SplitterFactory
{
public:
    virtual ISplitter *CreateSplitter()
    {
        return new TxtSplitter;
    }
};


新增加的例子

例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zedjay_

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值