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之外(类比将变化赶到一个小范围),使其更加可控,从而使文件分割器的设计和使用满足面向对象设计原则,在应对变化时表现出优势。

 1 //FileSpiltter1.cpp
 2 class ISplitter{
 3 public:
 4     virtual void split()=0;
 5     virtual ~ISplitter(){}
 6 };
 7
 8 class BinarySplitter : public ISplitter{
 9
10 };
11
12 class TxtSplitter: public ISplitter{
13
14 };
15
16 class PictureSplitter: public ISplitter{
17
18 };
19
20 class VideoSplitter: public ISplitter{
21
22 };
23
24 //MaiForm1.cpp
25 class MainForm : public Form
26 {
27     TextBox* txtFilePath;
28     TextBox* txtFileNumber;
29     ProgressBar* progressBar;
30
31 public:
32     void Button1_Click(){
33
34
35
36         ISplitter * splitter=
37             new BinarySplitter();//依赖具体类
38
39         splitter->split();
40
41     }
42 };

 1 //ISpiltterFactory.cpp
 2
 3 //抽象类
 4 class ISplitter{
 5 public:
 6     virtual void split()=0;
 7     virtual ~ISplitter(){}
 8 };
 9
10
11 //工厂基类
12 class SplitterFactory{
13 public:
14     virtual ISplitter* CreateSplitter()=0;
15     virtual ~SplitterFactory(){}
16 };
17
18 //FileSpiltter2.cpp
19
20 //具体类
21 class BinarySplitter : public ISplitter{
22
23 };
24
25 class TxtSplitter: public ISplitter{
26
27 };
28
29 class PictureSplitter: public ISplitter{
30
31 };
32
33 class VideoSplitter: public ISplitter{
34
35 };
36
37 //具体工厂
38 class BinarySplitterFactory: public SplitterFactory{
39 public:
40     virtual ISplitter* CreateSplitter(){
41         return new BinarySplitter();
42     }
43 };
44
45 class TxtSplitterFactory: public SplitterFactory{
46 public:
47     virtual ISplitter* CreateSplitter(){
48         return new TxtSplitter();
49     }
50 };
51
52 class PictureSplitterFactory: public SplitterFactory{
53 public:
54     virtual ISplitter* CreateSplitter(){
55         return new PictureSplitter();
56     }
57 };
58
59 class VideoSplitterFactory: public SplitterFactory{
60 public:
61     virtual ISplitter* CreateSplitter(){
62         return new VideoSplitter();
63     }
64 };
65
66 //MainForm2.cpp
67 class MainForm : public Form
68 {
69     SplitterFactory*  factory;//工厂
70
71 public:
72
73     MainForm(SplitterFactory*  factory){
74         this->factory=factory;
75     }
76
77     void Button1_Click(){
78
79
80         ISplitter * splitter=
81             factory->CreateSplitter(); //多态new
82
83         splitter->split();
84
85     }
86 };

模式定义:

定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使得一个类的实例化延迟(目的:解耦 ,手段:虚函数)到子类。

类图:

总结:

Factory Method模式用于隔离类对象的使用者与具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。

Factory Method模式通过面向对象的手法,将所有创建的具体对象延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。

Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

时间: 2024-11-10 21:29:20

c++ 设计模式8 (Factory Method 工厂方法)的相关文章

设计模式之 Factory Method 工厂方法

看到的比较有意思的一篇描述工厂方法的文章. http://www.codeproject.com/Articles/492900/From-No-Factory-to-Factory-Method 总结一下有几点: 1.  工厂方法封装对类的构造,用户不需关心某个类的详细构造过程,给出条件即可.条件就是工厂create的参数. 2.  工厂方法的基类工厂需封装不变的内容在create函数内,将子类会变化的部分抽取出一个函数,交由子类override. 3.  每个子类工厂其实都是一个简单工厂,只

Factory Method 工厂方法模式

Factory method工厂方法模式是一种实现了“工厂”概念的面向对象设计模式.就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题.工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.” 创建一个对象常常需要复杂的过程,所以不适合包含在一个复合对象中.创建对象可能会导致大量的重复代码,可能会需要复合对象访问不到的信息,也可能提供不了足够级别的抽象,还可能并不是复合对象概念的一部分.工厂方法模式通

深入浅出设计模式 ------ Factory Method(工厂方法)

1. 定义: 一个用于创建对象的接口, 让子类决定实例化哪个类. 工厂方法使一个类的实例化延迟到子类. 2. 结构 3. 参与者(如上图) Product ---- 定义工厂方法所创建的对象接口 ConcreteProduct ---- 实现Product接口 Creator ---- 声明工厂方法, 该方法返回一个Product类型的对象 ConcreteCreator ---- 重新定义工厂方法返回一个ConcreteProduct实例 4. 实现 (1) 特例: 简单工厂(Simple F

Factory Method(工厂方法)-对象创建型模式

1.意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. 2.动机 框架使用抽象类定义和维护对象之间的关系.这些对象的创建通常也由框架负责. 3.适用性 当一个类不知道它所必须创建的对象的类的时候. 当一个类希望由它的子类来指定它所创建的对象的时候. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一局部化的时候. 4.结构 5.代码实例 class Product { public: vir

Factory Method工厂方法

“对象创建“模式 通过”对象创建“模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(以来具体类),从而支持对象创建的稳定.它是接口抽象之后的第一部工作. 典型模式:Factory Method,Abstract Factory,Prototype,Builder 动机(Motivation) 在软件系统中,经常面临着创建对象的工作:由于需求的变化,需要创建的对象的具体类型经常变化. 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种”封装机制“来避免客户程序和这种"具体

设计模式实例(Lua)笔记之一(Factory Method工厂方法模式)

1.描述 女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是"造人"的工作,这个词被现代人滥用了.这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛蓝的,水是清澈的,空气是清新的,太美丽了,然后就待时间长了就有点寂寞了,没有动物,这些看的到都是静态的东西呀,怎么办?别忘了是神仙呀,没有办不到的事情,于是女娲就架起了八卦炉(技术术语:建立工厂)开始创建人,具体过程是这样的:先是泥巴捏,然后放八卦炉里烤,再扔到地上成长,但是意外总是会产生的:第一次

四、Factory Method 工厂方法模式

需求:对象的创建由工厂统一创建,会使用到模板模式 代码清单: 工厂: public abstract class Factory { public abstract Product createProduct(String owner); public abstract void registerProduct(Product product); public final Product create(String owner){ Product p = createProduct(owner)

深入浅出设计模式 ------ Abstract Factory(抽象工厂)

一. 定义  提供一个创建一系列相关或相互依赖对象的接口, 而无需指定它们的具体类. 二. 结构 三. 参与者 Product (Fruit和Leaf两个抽象产物) : 抽象生产者接口: TreeFruit(树上的水果). TreeLeaf(树上的叶子). GroundFruit(地上的水果). GroundLeaf(地上的叶子) : 实际的自然产物: NatureFactory: 抽象的自然制造工厂, 用于生产水果和叶子: TreeFactory. LeafFactory : 实际的自然制造工

设计模式04: Factory Methord 工厂方法模式(创建型模式)

Factory Methord 工厂方法模式(创建型模式) 从耦合关系谈起耦合关系直接决定着软件面对变化时的行为 -模块与模块之间的紧耦合使得软件面对变化时,相关的模块都要随之变更 -模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其他模块保持不变 对代码的关注要在理解了设计模式之后,对于不同的代码但是解决的是同一类问题,他们就是同一种设计模式.解决了哪一类的问题就是哪一类的设计模式. 软件需求的变化是软件工程的一部分,是我们要解决的问题. 把模块分为主模块.次模块主模