程序设计模式 —— 抽象工厂模式

前言



工厂?意思是创建变量的厂子?要这个干什么?为什么不直接new new new!!

定义:为创建一组相关或相互依赖的对象提供一个接口,而无需指定他们的具体类。

但是,从现在开始,请不要再使用new。

“What?不使用new?你怎么写C++程序,怎么写Java程序?”

我应该如何阅读?



本文将使用优雅的文字风格来告诉你什么是工厂模式。

注意:

  1.在阅读本文之前请保证你已经掌控了 面对对象的思想与 多态的基本概念,否则将难以理解。

  2.本文实现将用C++实现,你不一定必须学会C++,这些代码都有非常丰富的注释和简单的语法。

  3.请不要跳着看,除非你已经学会。

什么是工厂模式?



准确的说,工厂有两个,一个是简单工厂,一个是抽象工厂。

在《HeadFrist 设计模式》 一书当中说道:”简单工厂其实不是一个设计模式,更像是一种编程习惯,有些开发人员的确误以为是工厂模式。“

简单工厂是什么?



简单工厂顾名思义,十分简单,请看下面少量代码

注意:Entity 是一个抽象类,HelicopterA 是直升机A类型继承Entity HelicopterB 是直升机B类型继承Entity,暂且无需管具体代码,下面代码不影响。

 1 /*这是一个直升机工厂*/
 2 class HelicopterFactory
 3 {
 4 public:
 5     virtual Entity* create(const char* name)
 6     {
 7         Entity *p = NULL;
 8         if(name == "A"){
 9             cout << "[Factory] create: HelicopterA" << endl;
10             p = new HelicopterA();
11         }
12         if(name == "B"){
13             cout << "[Factory] create: HelicopterB" << endl;
14             p = new HelicopterB();
15         }
16         /**
17          if(name == "B"){
18             cout << "[Factory] create: HelicopterB" << endl;
19             p = new HelicopterB();    //更多更多的 产品
20             //这样,你的创建都集中在了一个类中间。当然了工厂模式不止这点点。
21         }
22         */
23         return p;
24     };
25 };

注意:如果你不会 C++,也没有关系,”Virtual” 关键字你可以无视,可以用Java的思想去看待代码

然后我们写主函数:

 1 HelicopterFactory hFactory = new HelicopterFactory();
 2     Entity *heli = hFactory->create("A");
 3     /*报告老板,我已经造好了直升机!*/
 4     heli->exec();
 5     heli = hFactory->create("B");
 6         heli = hFactory->create("B");    //我们这样就可以随意创建
 7         heli = hFactory->create("B");
 8         heli = hFactory->create("B");
 9         heli = hFactory->create("B");
10     /*报告老板,我已经造好了直升机!*/
11     heli->exec();//

至此,我们的简单工厂就是这样,看起来就是将创建的代码放到了一个专门的类里面了。

就这么简单?是的,简单工厂就这么简单。

但是如果我们要创建航天飞机呢?这个时候我们就要用到抽象工厂了。事实上也十分容易。设计模式其实都是很简单的,之所以出现了设计模式就是为了解决问题。

抽象工厂又是什么?



实现框架图:务必仔细看看

说白了就是我们可以创建各种各样的工厂,但是在实际使用的时候,我们是不需要知道究竟是哪个工厂。

我们来看看Entity类

 1 /*实体类 基类抽象类*/
 2 class Entity
 3 {
 4 public:
 5     Entity()
 6     {
 7
 8     };
 9     virtual ~Entity()
10     {
11
12     };
13     virtual void exec()=0;    //启动 交给子类实现
14 };

然后我们来实现 直升机航天飞机

 1 /*直升机类 类型A*/
 2 class HelicopterA : public Entity
 3 {
 4 public:
 5     virtual void exec()
 6     {
 7         cout << "HelicopterA Fly!" << endl;
 8     }
 9 };
10 /*直升机类 类型B*/
11 class HelicopterB : public Entity
12 {
13 public:
14     virtual void exec()
15     {
16         cout << "HelicopterB Fly!" << endl;
17     }
18 };
19
20 /*航天飞机 类型A*/
21 class ShuttleA : public Entity
22 {
23 public:
24     virtual void exec()
25     {
26         cout << "ShuttleA Fly!" << endl;
27     }
28 };
29
30 /*航天飞机 类型B*/
31 class ShuttleB : public Entity
32 {
33 public:
34     virtual void exec()
35     {
36         cout << "ShuttleB Fly!" << endl;
37     }
38 };

好的,到现在为止我们已经有了 “产品”,现在我们应该来制作 “工厂”了:

首先实现抽象工厂类:

 1 /*抽象工厂类*/
 2 class AbstractFactory
 3 {
 4 public:
 5     virtual ~AbstractFactory()
 6     {
 7
 8     };
 9     virtual Entity* create(const char*)=0;//交给子类去实现,这是创建实例的方法
10 };

现在我们来写两个具体工厂,直升机工厂和航天飞机工厂(你总不可能认为直升机工厂能制造出 航天飞机吧?)

 1 /*这是一个直升机工厂*/
 2 class HelicopterFactory : public AbstractFactory
 3 {
 4 public:
 5     HelicopterFactory()
 6     {
 7         cout << "--Create HelicopterFactory--" << endl;
 8     };
 9     virtual ~HelicopterFactory()
10     {
11
12     };
13     virtual Entity* create(const char* name)
14     {
15         Entity *p = NULL;
16         if(name == "A"){  //根据你要的名字来进行相应的new
17             cout << "[Factory] create: HelicopterA" << endl;
18             p = new HelicopterA();
19         }
20         if(name == "B"){                              
21             cout << "[Factory] create: HelicopterB" << endl;
22             p = new HelicopterB();    //根据你要的名字来进行相应的new
23         }
24         /**
25          if(name == "B"){
26             cout << "[Factory] create: HelicopterB" << endl;
27             p = new HelicopterB();    //更多更多的 产品
28             //这样,你的创建都集中在了一个类中间。当然了工厂模式不止这点点。
29         }
30         */
31         return p;
32     };
33 };
34
35 /*这是一个航天飞机工厂*/
36 class ShuttleFactory : public AbstractFactory
37 {
38 public:
39     ShuttleFactory()
40     {
41         cout << "--Create ShuttleFactory--" << endl;
42     };
43     virtual ~ShuttleFactory()
44     {
45
46     };
47     virtual Entity* create(const char* name)
48     {
49         Entity *p = NULL;
50         if(name == "A"){//根据你要的名字来进行相应的new
51             cout << "[Factory] create: ShuttleA" << endl;
52             p = new ShuttleA();
53         }
54         if(name == "B"){//根据你要的名字来进行相应的new
55             cout << "[Factory] create: ShuttleB" << endl;
56             p = new ShuttleB();
57         }
58         /*更多 种类的航天飞机*/
59         return p;
60     };
61 };

厂子应该要开工了!



现在我们写主函数:

“很好,你现在是 Pattern Art Online (R) 公司的员工,现在老板希望你为他在 Pattern Art Online 世界里面开个厂子,你十分肯定的说对于OO(object orient)程序员来说,这尼玛太简单了。。

“你的大脑中已经出现了老板表扬的场景....”

 1 int main(int argc, char const *argv[])
 2 {
 3     /*好的,我们现在来创建一个抽象工厂*/
 4     AbstractFactory *hFactory;
 5     /*具体化成 直升机工厂*/
 6     hFactory = new HelicopterFactory();
 7     /*然而我们并不需要管到底是什么,反正create就对了!*/
 8     Entity *heli = hFactory->create("A");
 9     /*报告老板,我已经造好了直升机!*/
10     heli->exec();
11     /*并且已经 可以启动了*/
12     /*什么?客户换需求了?要求航天飞机?好吧*/
13     /*幸好我用的是抽象的工厂,反正代码还是那样,只是需要换一个...*/
14     delete hFactory;    //嘿!别忘记释放原先了,
15     //这可不是Java语言,老实说我挺喜欢手动释放的,让我感觉什么都是我操作。好吧不扯这些了
16     hFactory = new ShuttleFactory();
17     /*制造*/
18     Entity *ent = hFactory->create("B");
19     ent->exec();//运行
20     Entity *www = hFactory->create("A");//制造
21     www->exec();//运行
22
23     /*恭喜你,我相信你已经学会了 抽象工厂模式*/
24     cin.get();//无视。由于我没有使用IDE,所以cin.get只是用于 暂停控制台
25     return 0;
26 }

“很好,这一次,你总算没有任何作弊行为和差错完成了。等等,为什么要加个总算?(具体故事情节在其他设计模式文章中)”

 这个例子不是很好的体现了 抽象工厂的优势。但是主要是要你学习。

说明一下:

下面的话比较重要,建议仔细看看(别不承认,我保证你一定跳着在看)

我们声明的

1 AbstractFactory *hFactory;

是一个抽象工厂,它可以被其他子类/其他函数 赋值任何类型的工厂,但是我们只需要使用 create 成员函数 就可以直接创建,根本不需要管到底是什么工厂,因为对于我们来说是抽象的。

而且不知道你有没有发现,我们返回的也是 Entity 抽象类 这表示我们的主函数也不需要知道到底是 直升机 还是 航天飞机 ,反正调用 exec 成员函数 就对了。

整个就是抽象,根本不知道处理的究竟是什么,但是又很好的支持所有。

"其实我个人认为,也许有很多人也这么认为,程序员的主要解决问题的途径就是将问题抽象,抽象抽象再抽象。然后我们便可以适应问题。"

就这样结束了?



“你获得了老板的表扬,你的队友也敬佩你的才能,听说下个月你的工资又要涨( ̄︶ ̄)了”

“最重要的是,你的队友答应你加入 Pattern Art Online (AR)空战游戏的《Fly!Fly!Fly!》战队了,而且他们原谅了你之前的坠机失误。(这件事情发生在: 《设计模式——状态模式》)”

至此,我相信你已经会了这个模式。

什么?你告诉我你没完全懂?这个时候其实你应该配合代码和框架图组合来看,你一定会明白的。复习复习。

最后



  但是要注意的一点,不是说有了这个模式,就必须要加进去使用,程序会更棒。

设计模式要与你的程序相互和谐,不能写个 “HelloWorld” 程序都用到了设计模式。

总的一句话,设计模式不是规则,而是你随时可以改变的模式。这也是很多设计模式书籍强调的一点。

不论对你是否有帮助,还是谢谢您的耐心查看。如有错误之处,还望指教。

时间: 2024-12-16 07:15:46

程序设计模式 —— 抽象工厂模式的相关文章

Java研究之学习设计模式-抽象工厂模式详解

 简介:          当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产[1] 品角色都有两个具体产品.抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化.每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例. 每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式针对的是多个产品等级结构.(摘自百度百科) 话语说得太抽象,程序员最好的表示方式

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

设计模式——抽象工厂模式学习

要想正确的理解设计模式,首先必须明确它是为了解决什么问题而提出来的. 抽象工厂设计模式概念: 针对抽象工厂这个设计模式,我查找了不少资料,感觉只有涉及产品级别和产品族的才是理解了抽象工厂设计模式的精髓,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式针对的是多个产品等级结构.有些观点认为抽象工厂模式是为了解决客户端代码与工厂类的耦合问题,我认为这种观点的解决方案只是简单工厂模式的一个应用,而这种观点认为的抽象工厂模式是: 工厂模式+简单工厂模式=抽象工厂模式,这是不正确. 针对的问题: 针对

设计模式 - 抽象工厂模式(abstract factory pattern) 详解

抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 参考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要明确指定具体类. 全部代码: http://download.csdn.net/de

设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释

抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 參考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不须要明白指定详细类. 所有代码: http://download.csdn.net/

Android设计模式——抽象工厂模式(Abstract Factory)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import

php设计模式——抽象工厂模式(Abstract Factory)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 <?php 2 /* 3 * php设计模式——抽象工厂模式(Abstract Factory) 4 */ 5 6 7 /* 8 * I

5. 星际争霸之php设计模式--抽象工厂模式

题记==============================================================================本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦! 本文地址:http://www.cnblogs.com/davidhhuan/p/4248178.html============================================

JAVA设计模式--抽象工厂模式

抽象工厂设计模式 1.系统中有多个产品族,而系统一次只可能消费其中一族产品2.同属于同一个产品族的产品以其使用.来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关的代码.由应用程序调用以创建对应的具体产品的对象.在java中它由具体的类来实现.抽象产品角色:它是具体产品继承的父类或者是实现的接口.在java中一般