c++ 设计模式8 (Factory Method 工厂方法)
5. “对象创建”类模式
通过“对象创建”类模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
5.1 工厂方法
动机:
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
代码示例:
仍然考虑文件分割器案例,不考虑与创建对象无关的代码部分,暂时忽略内存管理,专注于工厂方法模式的应用。
在实现代码1中,不同类型的文件分割器类(File,Pic,Video等)继承文件分割器抽象基类。
在MainForm中,MainForm类依赖(编译时依赖)了具体的类BinarySpitter,违背了依赖倒置原则。此时即出现了动机中说明的创建对象过程中导致的紧耦合。
采用工厂方法模式的解决方案见代码2,考虑过程如下:
1.利用new方法创建的对象必须依赖于具体类,不可取;所以考虑创建一个类,利用其中方法的返回值作为创建对象的结果;
2.然而单纯的返回一个具体类的对象仍然没有解决依赖倒置的问题,所以考虑将该类设计为一个抽象类,具体的返回由其子类来确定。
3.依照上述思想创建工厂基类SplitterFactory(抽象类),具体工厂(BinarySplitterFactory等)返回具体的对象。
4.MainForm使用过程中,声明一个工厂字段,在具体创建对象过程中采用统一的依赖于抽象的创建方法,即
ISplitter * splitter= factory->CreateSplitter(); //相当于多态new
而factory具体指向的对象类型由MainForm构造函数通过外界传入。
注:可以从上述分析和代码中看出,工厂方法模式的使用,并不是为了消除变化(事实上变化不可能消除),而是将变化排除在MainForm之外(类比将变化赶到一个小范围),使其更加可控,从而使文件分割器的设计和使用满足面向对象设计原则,在应对变化时表现出优势。
//FileSpiltter1.cpp
class ISplitter{
public:
virtual void split()=;
virtual ~ISplitter(){}
}; class BinarySplitter : public ISplitter{ }; class TxtSplitter: public ISplitter{ }; class PictureSplitter: public ISplitter{ }; class VideoSplitter: public ISplitter{ }; //MaiForm1.cpp
class MainForm : public Form
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar; public:
void Button1_Click(){ ISplitter * splitter=
new BinarySplitter();//依赖具体类 splitter->split(); }
};
//ISpiltterFactory.cpp //抽象类
class ISplitter{
public:
virtual void split()=;
virtual ~ISplitter(){}
}; //工厂基类
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=;
virtual ~SplitterFactory(){}
}; //FileSpiltter2.cpp //具体类
class BinarySplitter : public ISplitter{ }; class TxtSplitter: public ISplitter{ }; class PictureSplitter: public ISplitter{ }; class VideoSplitter: public ISplitter{ }; //具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new BinarySplitter();
}
}; class TxtSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new TxtSplitter();
}
}; class PictureSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new PictureSplitter();
}
}; class VideoSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new VideoSplitter();
}
}; //MainForm2.cpp
class MainForm : public Form
{
SplitterFactory* factory;//工厂 public: MainForm(SplitterFactory* factory){
this->factory=factory;
} void Button1_Click(){ ISplitter * splitter=
factory->CreateSplitter(); //多态new splitter->split(); }
};
模式定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使得一个类的实例化延迟(目的:解耦 ,手段:虚函数)到子类。
类图:

总结:
Factory Method模式用于隔离类对象的使用者与具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
Factory Method模式通过面向对象的手法,将所有创建的具体对象延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。
c++ 设计模式8 (Factory Method 工厂方法)的更多相关文章
- Java设计模式:Factory Method(工厂方法)模式
概念定义 工厂方法(Factory Method)模式,又称多态工厂(Polymorphic Factory)模式或虚拟构造器(Virtual Constructor)模式.工厂方法模式通过定义工厂抽 ...
- 设计模式之 Factory Method 工厂方法
看到的比较有意思的一篇描述工厂方法的文章. http://www.codeproject.com/Articles/492900/From-No-Factory-to-Factory-Method 总 ...
- Factory Method 工厂方法模式
Factory method工厂方法模式是一种实现了“工厂”概念的面向对象设计模式.就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题.工厂方法模式的实质是“定义一个创建对象 ...
- 面向对象设计模式纵横谈:Factory Method 工厂方法模式(笔记记录)
从耦合关系谈起 耦合关系直接决定着软件面对变化时的行为 -模块与模块之间的紧耦合使得软件面对变化时,相关模块都要随之更改 -模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其 ...
- C#面向对象设计模式纵横谈——5.Factory Method 工厂方法模式(创建型模式)
动机 (Motivation) 在软件系统中,经常面临着“某个对象”的创建工作; 由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何应对这种变化?如何提供一种“封装机制” ...
- 设计模式C++学习笔记之五(Factory Method工厂方法模式)
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的 ...
- Factory Method(工厂方法)-对象创建型模式
1.意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. 2.动机 框架使用抽象类定义和维护对象之间的关系.这些对象的创建通常也由框架 ...
- 3.Factory Method 工厂方法模式(创建型模式)
1.定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使得一个类的实例化延迟到子类. 2.实现代码如下: /// <summary> /// 工厂方 ...
- Factory Method工厂方法模式
定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类,属于创建型模式 在此模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生产 ...
随机推荐
- ASP.NET MVC - 发布网站
原文地址:http://www.w3school.com.cn/aspnet/mvc_publish.asp 学习如何在不使用 Visual Web Developer 的情况下发布 MVC 应用程序 ...
- 第三百四十九、五十天 how can I 坚持
昨天是忘写博客了,今天下班才突然意思到,搞框架搞了好晚.今天重新下了个好了. 昨天,把存储过程交给同事写了,啥都不会,又一堆问题,折腾了一天. 今天相对轻松些,不过事情还没完..明天又周五了. 还有昨 ...
- 网上关于sort结构体排序都不完整,我来写一个完整版的 2014-08-09 16:50 60人阅读 评论(0) 收藏
主要参考sort函数_百度文库, 但是那篇有错误 2.结构体排序,a升,b降,c降 平板视图 打印? 01 #include <iostream> 02 #include <algo ...
- 左手坐标系&右手坐标系
[左手坐标系&右手坐标系] 左手坐标系的正方向.从原点看到某轴正向时,逆时针即为正方向.相反地,从某轴正方向看看原点时,为顺时针即为正方向. 如果判断左手坐标系下叉积的方向.如果A.B向量首尾 ...
- vim切换buffer
[vim切换buffer] 命令 ls 可查看当前已打开的buffer 命令 b num 可切换buffer (num为buffer list中的编号) 其它命令: :bn -- buffer列表中下 ...
- USB开发库文件分析
stm32f10x_it.c: 该文件中包含 USB 中断服务程序,由于 USB 中断有很多情况,这里的中断服务程序只是调用 usb_Istr.c 文件中的 USB_Istr 函数,由 USB_Ist ...
- labview事件结构
等待事件发生,并执行相应条件分支,处理该事件.事件结构 包括一个或多个子程序框图或事件分支,结构处理时间时,仅有一个子程序框图或分支在执行.等待事件通知时,该结构可超时. 连线边框左上角的“超时”接线 ...
- 埃氏筛法(快速筛选n以内素数的个数)
给你一个数n,请问n以内有多少个素数?(n <= 10e7) 一般来说,要是对一个整数进行素数判断,首先想到的是写个函数判断是否为素数,然后调用这个函数,时间复杂度为O(n^(½)),但是要求n ...
- tableviewcell 系统工具删除:左滑删除,选中多个删除
在编辑tableview的时候,我们有时候会需要编辑对一些cell进行删除(增加),在这个时候,我们最好用系统的方法来进行增删的操作 // // text1Controller.m // text / ...
- Custom ReadOnlyProperty【PluraSight】
Limited functionality: Not settable No data binding No validation No animation No Inheritance When t ...