大话设计模式:简单工厂模式
2016-07-16 16:33
239 查看
由于面向过程编程造成的代码膨胀问题越来越严重,使其维护的代价高,灵活性很低。为了使代码易维护、易扩展、易复用和灵活性好,所以我们在采用面向对象编程的时候,防止采用面向对象的语言实际上却做着面向过程的事儿,更需要采用某种设计模式,核心就是使程序变得高内聚,低耦合,这样的程序才能达到上面的四个优点。而简单工厂模式的出现也正是为了达到这样一种效果,将工厂和产品分块,具体解决了实例化那个对象(具体产品)的需求。从而实现了高内聚,低耦合。使程序易维护、易扩展、易复用和灵活性好。同时也用到了面向对象编程的三大特性:继承、多态、封装。
简单工厂模式主要包括以下几个模块:
(1)工厂类Factory:在Factory中有一个用于制造产品的Create函数,用于制造产品。里面有个switch-case语句,这个函数能够根据“标识符”的不同生成不同的ConcreteProduct,当然这些ConcreteProduct都是继承自AbstractProduct的。
(2)抽象产品类:AbstructProduct:抽象产品是从其他具体产品抽象出来的。抽象产品类只有一个。
(3)具体产品类ConcreteProduct:具体产品类继承自抽象产品类,可以有多个。
以书上的计算器为例:
优点:实现了低耦合。当需要增加一种新产品(以添加开根号运算为例),只需要做两点改动:
(1)增加一个继承自抽象产品--抽象运算--的具体产品(添加一个开根号的类,继承Operation类);
(2)在工厂中,switch中,增加一种根据标识符产生新运算的case即可(添加一个case的变量,开根号);
缺点:只能生产一种类型的产品,该产品都继承抽象产品类(该书中所指的就是运算类:Operation类,每种具体的运算(+-*/)都需要继承该类。但是如果后来我们需要播放一首歌曲或者画出不同图形这样的功能,这个简单工厂模式就不行了,具体实现思想后面再介绍。因为它只能实现某一类抽象的产品,)。
其UML图如下:
![](https://img-blog.csdn.net/20160716163240203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
其具体实现代码:
运行结果:
简单工厂模式主要包括以下几个模块:
(1)工厂类Factory:在Factory中有一个用于制造产品的Create函数,用于制造产品。里面有个switch-case语句,这个函数能够根据“标识符”的不同生成不同的ConcreteProduct,当然这些ConcreteProduct都是继承自AbstractProduct的。
(2)抽象产品类:AbstructProduct:抽象产品是从其他具体产品抽象出来的。抽象产品类只有一个。
(3)具体产品类ConcreteProduct:具体产品类继承自抽象产品类,可以有多个。
以书上的计算器为例:
优点:实现了低耦合。当需要增加一种新产品(以添加开根号运算为例),只需要做两点改动:
(1)增加一个继承自抽象产品--抽象运算--的具体产品(添加一个开根号的类,继承Operation类);
(2)在工厂中,switch中,增加一种根据标识符产生新运算的case即可(添加一个case的变量,开根号);
缺点:只能生产一种类型的产品,该产品都继承抽象产品类(该书中所指的就是运算类:Operation类,每种具体的运算(+-*/)都需要继承该类。但是如果后来我们需要播放一首歌曲或者画出不同图形这样的功能,这个简单工厂模式就不行了,具体实现思想后面再介绍。因为它只能实现某一类抽象的产品,)。
其UML图如下:
其具体实现代码:
#include <iostream> using namespace std; //抽象产品类 class Operation { protected: double numberA; double numberB; public: double getA() { return numberA; } double getB() { return numberB; } void setA(double number) { numberA=number; } void setB(double number) { numberB=number; } virtual double GetResult() { double result=0; return result; } }; //下面是四种具体产品类,只能是同一类的产品; class OperationAdd:public Operation { public: double GetResult() { double result=0; result=numberA+numberB; return result; } }; class OperationSub:public Operation { public: double GetResult() { double result=0; result=numberA-numberB; return result; } }; class OperationMul:public Operation { public: double GetResult() { double result=0; result=numberA*numberB; return result; } }; class OperationDiv:public Operation { public: double GetResult() { double result=0; if(numberB!=0) result=numberA/numberB; return result; } }; //工厂类,决定实例化那个产品; class OperationFactory { public: Operation* createOperation(char type) { Operation* oper; switch(type) { case '+': oper=new OperationAdd; break; case '-': oper=new OperationSub; break; case '*': oper=new OperationMul; break; case '/': oper=new OperationDiv; break; } return oper; } }; //客户端 int main() { Operation* oper=NULL; OperationFactory of; oper=of.createOperation('+'); oper->setA(3); oper->setB(2); cout<<oper->GetResult()<<endl; if(oper!=NULL) { delete oper; oper=NULL; } system("pause"); return 0; }
运行结果:
相关文章推荐
- 关于大数取模
- 哲学与哲学家的观点大作战
- APP开发实战90-矢量图介绍
- mysql 结合keepalived测试
- 两行代码自定义cell选中颜色
- CV | SIFTflow 学习笔记
- C++Primer 变量和基本类型
- mysql 结合keepalived测试
- mysql 结合keepalived测试
- MapReduce中的map个数
- HTTP深入浅出之http请求和15中以上的请求方式
- CSS实现三列图片等宽等间距布局
- spark官方文档中文版
- Codeforces Round #362 B. Barnicle JAVA高精度
- CentOS6.7下安装MySQL
- nginx使用ssl模块配置支持HTTPS访问 AND 开启gzip
- 【COCI2012 Task 5】T6 poplocavanje ([JZOJ3172]贴瓷砖)(AC自动机模板)
- 冒泡排序
- CodeForces 691D Swaps in Permutation (并查集 + 双向链表)
- 2016.07.16【初中部 NOIP提高组 】模拟赛C总结