设计模式之工厂方法模式20170801

创建型设计模式之工厂方法模式:

一、含义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

通俗来说就是,使用工厂类来创建产品类(传入不同的实现类(类名或其标识)返回相应的对象)

二、代码说明

1.主要有两个角色

1)产品类

表示产品

2)创建类(工厂类)

负责创建产品类

2.在用C实现过程中也是参考这种思想,以进生产超人举例,具体实现如下:

1)工厂方法模式使用场景:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     FactoryMethodPatternUsage.c
 5 * Description        :     工厂方法模式的使用
 6 
 7 book@book-desktop:/work/projects/test/DesignPatterns/FactoryMethodPattern$ gcc -o FactoryMethodPatternUsage AdultSuperMan.c ChildSuperMan.c FactoryMethodPattern.c FactoryMethodPatternUsage.c 
 8 book@book-desktop:/work/projects/test/DesignPatterns/FactoryMethodPattern$ ./FactoryMethodPatternUsage 
 9 ------------生产成年超人:------------
10 超人力大无穷
11 -----------生产未成年超人:-----------
12 小超人的能力是刀枪不入,快速运动
13 
14 * Created            :     2017.07.31.
15 * Author            :     Yu Weifeng
16 * Function List         :     
17 * Last Modified     :     
18 * History            :     
19 ******************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "FactoryMethodPattern.h"
24 
25 
26 
27 
28 /*****************************************************************************
29 -Fuction        : main
30 -Description    : 
31 -Input            : 
32 -Output         : 
33 -Return         : 
34 * Modify Date      Version         Author           Modification
35 * -----------------------------------------------
36 * 2017/07/31    V1.0.0         Yu Weifeng       Created
37 ******************************************************************************/
38 int main(int argc,char **argv)
39 {
40     T_SuperManFactory tSuperManFactory=newSuperManFactory;
41     T_SuperMan tSuperMan;
42     printf("------------生产成年超人:------------
");
43     tSuperMan=tSuperManFactory.CreatSuperMan("adult");
44     tSuperMan.SuperManTalent();
45     printf("-----------生产未成年超人:-----------
");
46     tSuperMan=tSuperManFactory.CreatSuperMan("child");
47     tSuperMan.SuperManTalent();    
48     return 0;
49 }
FactoryMethodPatternUsage.c

2)被调用者:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     FactoryMethodPattern.c
 5 * Description        :     工厂方法模式
 6                         本文件是超人生产工厂的具体实现
 7                         以进生产超人举例    
 8                         
 9 * Created            :     2017.07.31.
10 * Author            :     Yu Weifeng
11 * Function List         :     
12 * Last Modified     :     
13 * History            :     
14 ******************************************************************************/
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include "FactoryMethodPattern.h"
19 
20 
21 void AdultTalent();
22 #define newAdultTalent {AdultTalent}
23 void ChildTalent();
24 #define newChildTalent {ChildTalent}
25 
26 /*****************************************************************************
27 -Fuction        : CreatSuperMan
28 -Description    : 公有函数
29 -Input            : 
30 -Output         : 
31 -Return         : 
32 * Modify Date      Version         Author           Modification
33 * -----------------------------------------------
34 * 2017/07/31    V1.0.0         Yu Weifeng       Created
35 ******************************************************************************/
36 T_SuperMan CreatSuperMan(char *i_strType)
37 {
38     T_SuperMan tSuperMan={NULL};
39     if(0==strcmp("adult",i_strType))
40     {
41         tSuperMan=(T_SuperMan)newAdultTalent;
42     }
43     else if(0==strcmp("child",i_strType))
44     {
45         tSuperMan=(T_SuperMan)newChildTalent;
46     }
47     else
48     {
49         printf("CreatSuperMan err,UnkownType:%s",i_strType);
50     }
51     return tSuperMan;
52 }
FactoryMethodPattern.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     FactoryMethodPattern.h
 5 * Description        :     工厂方法模式
 6                                     
 7 * Created            :     2017.07.31.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #ifndef FACTORY_METHOD_PATTERN_H
14 #define FACTORY_METHOD_PATTERN_H
15 
16 typedef struct SuperMan
17 {
18     void (*SuperManTalent)();
19     
20 }T_SuperMan;
21 
22 typedef struct SuperManFactory
23 {
24     T_SuperMan (*CreatSuperMan)(char *i_strSuperManType);
25     
26 }T_SuperManFactory;
27 
28 
29 
30 T_SuperMan CreatSuperMan(char *i_strType);
31 #define newSuperManFactory {CreatSuperMan}
32 
33 
34 #endif
FactoryMethodPattern.h
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     AdultSuperMan.c
 5 * Description        :     工厂方法模式
 6                         本文件是成年超人的具体实现
 7                         
 8 * Created            :     2017.07.31.
 9 * Author            :     Yu Weifeng
10 * Function List         :     
11 * Last Modified     :     
12 * History            :     
13 ******************************************************************************/
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "FactoryMethodPattern.h"
18 
19 
20 
21 /*****************************************************************************
22 -Fuction        : AdultTalent
23 -Description    : 公有函数
24 -Input            : 
25 -Output         : 
26 -Return         : 
27 * Modify Date      Version         Author           Modification
28 * -----------------------------------------------
29 * 2017/07/31    V1.0.0         Yu Weifeng       Created
30 ******************************************************************************/
31 void AdultTalent()
32 {
33     printf("超人力大无穷
");
34 
35 }
AdultSuperMan.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ChildSuperMan.c
 5 * Description        :     工厂方法模式
 6                         本文件是未成年超人的具体实现
 7                         
 8 * Created            :     2017.07.31.
 9 * Author            :     Yu Weifeng
10 * Function List         :     
11 * Last Modified     :     
12 * History            :     
13 ******************************************************************************/
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "FactoryMethodPattern.h"
18 
19 
20 
21 /*****************************************************************************
22 -Fuction        : ChildTalent
23 -Description    : 公有函数
24 -Input            : 
25 -Output         : 
26 -Return         : 
27 * Modify Date      Version         Author           Modification
28 * -----------------------------------------------
29 * 2017/07/31    V1.0.0         Yu Weifeng       Created
30 ******************************************************************************/
31 void ChildTalent()
32 {
33     printf("小超人的能力是刀枪不入,快速运动
");
34 
35 }
ChildSuperMan.c

3)执行结果:

book@book-desktop:/work/projects/test/DesignPatterns/FactoryMethodPattern$ gcc -o FactoryMethodPatternUsage AdultSuperMan.c ChildSuperMan.c FactoryMethodPattern.c FactoryMethodPatternUsage.c

book@book-desktop:/work/projects/test/DesignPatterns/FactoryMethodPattern$ ./FactoryMethodPatternUsage

------------生产成年超人:------------

超人力大无穷

-----------生产未成年超人:-----------

小超人的能力是刀枪不入,快速运动

4)详细代码:

https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/CreationalDesignPatterns/FactoryMethodPattern

三、使用场景

1.工厂方法模式是new对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否增加一个工厂类进行管理,增加代码的复杂度。

2.需要灵活的,可扩展的框架时,可以考虑采用工厂方法模式。

3.可以用在异构项目中,用一个具体的工厂类进行管理,减少与外围系统的耦合。

4.可以使用在测试驱动开发的框架下。例如,测试一个类A,就需要把与类A有关联关系的类B也同时产生出来,可以

使用工厂方法模式把类B虚拟出来,避免类A与类B的耦合。

四、优点

1.良好的封装性,代码结构清晰,实现了统一管理各个实现类

一个对象创建是具有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。

2.工厂方法模式的扩展性非常优秀

在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成拥抱变化。

3.屏蔽产品类

产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。

4.工厂方法模式是典型的解耦框架。

高层模块只需要知道产品的抽象类,其他的实现类都不用关心。

五、工厂方法模式的扩展

1.缩小为简单工厂模式

一个模块仅需要一个工厂类,没有必要把它产生出来,使用静态的方法就可以了。

2.升级为多个工厂类

在复杂的应用中一般采用多工厂的方法,然后再增加一个协调类,避免调用者与各个子工厂交流,协调类的作用是封装子工厂类,对高层模块提供统一的访问接口

3.替代单例模式

单例模式的核心要求就是在内存中只有一个对象,通过工厂方法模式也可以只在内存中生产一个对象。

4.延迟初始化

一个对象被消费完毕后,并不立科释放,工厂类保持其初始状态,等待再次被使用。

六、与其他模式的区别

1、工厂方法模式与建造者模式

工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程。具体来说,

1)意图不同

在工厂方法模式里,我们关注的是一个产品整体;但在建造这模式中,关注的是 由零件一步一步地组装出产品对象。

简单的说,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注的是产品组成部分的创建过程。

2)产品的复杂度不同

工厂方法模式创建的产品一般都是单一性质产品,都是一个模样;而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。

两种模式的选择,完全取决于在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

原文地址:https://www.cnblogs.com/yuweifeng/p/7270354.html