文章目录
- 0、模式类型
- 1、Factory Method
- 1.1、动机
- 1.2、实现
- 2、模式定义
- 3、结构
- 4、总结
0、模式类型
"对象创建"模式
- 通过“对象创建”模式绕开new,来避免对象创建(new)过程中导致的紧耦合(依赖具体类),从而支持对象创建的稳定。他是接口抽象之后的第一步工作。
典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
1、Factory Method
1.1、动机
- 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
- 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
1.2、实现
需求:假设现在有一个按钮,按钮点击一次产生某种文件分割的效果,现在是只有二进制文件分割的功能,以后需求可能会发生变化,可能会要有视频分割效果。
- 初始解决方案
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;
}
运行结果:
总结:这种解决方案的问题是会依赖MainButton类,以后如果需求变化需要修改代码。所以需要进行改进,让其能够应对未来的变化。
解决方案:我们在写代码的时候有一个原则,可以通过创造基类的方式来应对变化。
- 添加基类的方法
//
// 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;
}
运行结果:
总结:虽然Main_button左边能够应对变化,但是右边如果未来需求变化,还是需要修改代码。
解决方案:通过虚函数的手段让其从编译期的初始化变成运行时的初始化。
- 最终解决方案(工厂方法)
代码:
//
// 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;
}
运行结果:
2、模式定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解释,手段:虚函数)到子类。 ——《设计模式》GoF.