23设计模式—工厂方法

0、模式类型

"对象创建"模式

  • 通过“对象创建”模式绕开new,来避免对象创建(new)过程中导致的紧耦合(依赖具体类),从而支持对象创建的稳定。他是接口抽象之后的第一步工作。

典型模式

  • Factory Method
  • Abstract Factory
  • Prototype
  • Builder

1、Factory Method

1.1、动机

  • 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
  • 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?

1.2、实现

需求:假设现在有一个按钮,按钮点击一次产生某种文件分割的效果,现在是只有二进制文件分割的功能,以后需求可能会发生变化,可能会要有视频分割效果。

  1. 初始解决方案
class BinarySlice{
public:
    void Slice()
    {
        std::cout << "---BinarySlice---" << std::endl;
    }
};
#ifndef DESIGN_PATTERN_MAIN_BUTTON_H
#define DESIGN_PATTERN_MAIN_BUTTON_H
#include<iostream>
#include"Slice.h"
class MainButton{
public:
    void Button()
    {
        BinarySlice* slice = new BinarySlice();
        slice->Slice();
    }
};

#endif //DESIGN_PATTERN_MAIN_BUTTON_H

//
// Created by long on 2023/8/16.
//
#include<iostream>
#include"Main_button.h"
using namespace std;

int main()
{

    MainButton* button = new MainButton(); // 11,12行会依赖其他的类
    button->Button();

    return 0;
}

运行结果:
image.png
总结:这种解决方案的问题是会依赖MainButton类,以后如果需求变化需要修改代码。所以需要进行改进,让其能够应对未来的变化。
解决方案:我们在写代码的时候有一个原则,可以通过创造基类的方式来应对变化

  1. 添加基类的方法
//
// Created by long on 2023/9/1.
//

#ifndef MY_TEST_SLICE_H
#define MY_TEST_SLICE_H
#include<iostream>
class ISlice{
public:
    virtual void Slice() = 0;
    virtual ~ISlice(){}
};

class BinarySlice: public ISlice{
public:
    void Slice()
    {
        std::cout << "---BinarySlice---" << std::endl;
    }
};

class VideoSlice: public ISlice{
public:
    void Splitter()
    {
        std::cout << "---VideoSSlice---" << std::endl;
    }
};

class PictureSlice: public ISlice{
public:
    void Slice()
    {
        std::cout << "---PictureSlice---" << std::endl;
    }
};
#endif //MY_TEST_SLICE_H

//
// Created by long on 2023/9/1.
//

#ifndef DESIGN_PATTERN_MAIN_BUTTON_H
#define DESIGN_PATTERN_MAIN_BUTTON_H
#include<iostream>
#include"Slice.h"
class MainButton{
public:
    void Button()
    {
//        BinarySlice* slice = new BinarySlice();
        ISlice* slice = new BinarySlice(); //等号左边使用基类,可以应对变化,比较稳定,但是右边不稳定。
        slice->Slice();
    }
};

#endif //DESIGN_PATTERN_MAIN_BUTTON_H

//
// Created by long on 2023/8/16.
//
#include<iostream>
#include"Main_button.h"
using namespace std;

int main()
{

    MainButton* button = new MainButton();
    button->Button();
    return 0;
}

运行结果:
image.png
总结:虽然Main_button左边能够应对变化,但是右边如果未来需求变化,还是需要修改代码。
解决方案:通过虚函数的手段让其从编译期的初始化变成运行时的初始化。

  1. 最终解决方案(工厂方法)

代码:

//
// Created by long on 2023/9/1.
//

#ifndef MY_TEST_SLICE_H
#define MY_TEST_SLICE_H
#include<iostream>
class ISlice{
public:
    virtual void Slice() = 0;
    virtual ~ISlice(){}
};

class BinarySlice: public ISlice{
public:
    void Slice()
    {
        std::cout << "---BinarySlice---" << std::endl;
    }
};

class VideoSlice: public ISlice{
public:
    void Slice()
    {
        std::cout << "---VideoSlice---" << std::endl;
    }
};

class PictureSlice: public ISlice{
public:
    void Slice()
    {
        std::cout << "---PictureSlice---" << std::endl;
    }
};
#endif //MY_TEST_SLICE_H

//
// Created by long on 2023/9/1.
//

#ifndef DESIGN_PATTERN_SLICE_FACTORY_H
#define DESIGN_PATTERN_SLICE_FACTORY_H
#include<iostream>
#include"Slice.h"

class Slice_Factory{
public:
virtual ISlice* Factory() = 0;
virtual ~Slice_Factory(){}
};

class VideoSlice_Factory: public Slice_Factory{
public:
ISlice* Factory() override
{
    return new VideoSlice();
}
};

class BinarySlice_Factory: public Slice_Factory{
public:
ISlice* Factory() override
{
    return new BinarySlice();
}
};

class PictureSlice_Factory:  public Slice_Factory{
public:
ISlice* Factory() override
{
    return new PictureSlice();
}
};



#endif //DESIGN_PATTERN_SLICE_FACTORY_H
//
// Created by long on 2023/9/1.
//

#ifndef DESIGN_PATTERN_MAIN_BUTTON_H
#define DESIGN_PATTERN_MAIN_BUTTON_H
#include<iostream>
#include"Slice.h"
#include"Slice_Factory.h"
class MainButton{
public:
MainButton(Slice_Factory* factory)
{
    this->factory = factory;
}

void Button()
{
    //        BinarySlice* slice = new BinarySlice(); //1
    //        ISlice* slice = new BinarySlice(); //2等号左边使用基类,可以应对变化,比较稳定,但是右边不稳定。
    //        slice->Slice();
    ISlice* slice = factory->Factory(); // 通过传参将MainButton内部变为稳定,而不稳定的部分被赶出类外了。
    slice->Slice();
}

private:
Slice_Factory* factory;
};

#endif //DESIGN_PATTERN_MAIN_BUTTON_H
//
// Created by long on 2023/8/16.
//
#include<iostream>
#include"Main_button.h"
using namespace std;

int main()
{

    MainButton* button = new MainButton(new BinarySlice_Factory());
    button->Button();
    MainButton* button2 = new MainButton(new PictureSlice_Factory());
    button2->Button();

    return 0;
}

运行结果:
image.png

2、模式定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解释,手段:虚函数)到子类。 ——《设计模式》GoF.

3、结构

image.png

4、总结

image.png

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值