什么是简单工厂模式
工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。如数据库生产工厂就是简单工厂的一个应用
采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;缺点是可实例化的类型在编译期间已经被确定,如果增加新类 型,则需要修改工厂,不符合OCP(开闭原则)的原则。简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。
简单工厂模式实现
下面考虑《大话设计模式》中的一个例子:
题目:用任意一种面向对象语言实现一个计算器控制台程序。要求输入两个数和运算符号,得到结果。
题目分析:
程序应该做到:(1)可维护;(2)可复用;(3)可扩展;(4)灵活性好。
可维护:就是说代码一处更改,不能产生连锁反应,不能影响其他地方。
可复用:尽量减少重复性代码。
可扩展:如果要扩展新的功能、新的业务,则只需要增加新的类就好了,不对已有的类和逻辑产生影响。插拔式的应用。
面向对象要点:
面向对象三大特性:封装、继承、多态。
通过封装、继承、多态把程序耦合降低。
业务逻辑和界面逻辑分开。
类的结构图:
代码实现:
1. 首先,搞清楚业务中容易发生变化的部分。在本应用中,要求计算两个数的运算结果,那么要进行什么样的运算,这就是一个容易发生变化的部分。例如,我们现在只想实现加减乘除运算,后期又想增加开根或者求余运算。那么如何应对这种需求带来的变化。在程序设计的时候就应该考虑到程序的可维护性、可扩展性、代码的可复用性、灵活性等等。
2. 例如现在这个运算器只有加减乘除四种运算。首先建一个Operation类,这个类是各种具体运算类(加减乘除)的父类,主要是接受用户输入的数值。该类如下:
class Operation(): def __init__(self,NumberA=0,NumberB=0): self.NumberA = NumberA self.NumberB = NumberB def GetResult(self): pass
3. 然后是具体的运算类:Add、Sub、Mul、Div。他们都继承了Operation类,并且重写了getResult()方法。这样就可以用多态性降低不同业务逻辑的耦合度,修改任何一种运算类都不会影响其他的运算类。具体类的代码如下:
class AddOp(Operation): def GetResult(self): return self.NumberB + self.NumberA class MinusOp(Operation): def GetResult(self): return self.NumberA - self.NumberB class MultiOp(Operation): def GetResult(self): return self.NumberA * self.NumberB class DivideOp(Operation): def GetResult(self): try: return 1.0*self.NumberA / self.NumberB except ZeroDivisionError: raise
4. 那么如何让计算器知道我是要用哪一种运算呢?也就是说到底要实例化哪一个具体的运算类,Add?Sub?Mul?Div?这时就应该考虑用 一个单独的类来做这个创造具体实例的过程,这个类就是工厂类。如下:
class OperationFatory(): def ChooseOperation(self,op): if op == '+': return AddOp() if op == '-': return MinusOp() if op == '*': return MultiOp() if op == '/': return DivideOp()
5. 这样,用户只要输入运算符,工厂类就可以创建合适的实例,通过多态性,即返回给父类的方式实现运算结果。客户端代码如下:
if __name__ == '__main__': ch = '' while not ch=='q': NumberA = eval(raw_input('Please input number1: ')) op = str(raw_input('Please input the operation: ')) NumberB = eval(raw_input('Please input number2: ')) OPFactory = OperationFatory() OPType = OPFactory.ChooseOperation(op) OPType.NumberA = NumberA OPType.NumberB = NumberB print 'The result is:',OPType.GetResult() print '\n#-- input q to exit any key to continue' try: ch = str(raw_input()) except: ch = ''
完整版代码如下:
# -*-coding:UTF-8-*- from abc import ABCMeta,abstractmethod class Operation(): def __init__(self,NumberA=0,NumberB=0): self.NumberA = NumberA self.NumberB = NumberB def GetResult(self): pass class AddOp(Operation): def GetResult(self): return self.NumberB + self.NumberA class MinusOp(Operation): def GetResult(self): return self.NumberA - self.NumberB class MultiOp(Operation): def GetResult(self): return self.NumberA * self.NumberB class DivideOp(Operation): def GetResult(self): try: return 1.0*self.NumberA / self.NumberB except ZeroDivisionError: raise class OperationFatory(): def ChooseOperation(self,op): if op == '+': return AddOp() if op == '-': return MinusOp() if op == '*': return MultiOp() if op == '/': return DivideOp() if __name__ == '__main__': ch = '' while not ch=='q': NumberA = eval(raw_input('Please input number1: ')) op = str(raw_input('Please input the operation: ')) NumberB = eval(raw_input('Please input number2: ')) OPFactory = OperationFatory() OPType = OPFactory.ChooseOperation(op) OPType.NumberA = NumberA OPType.NumberB = NumberB print 'The result is:',OPType.GetResult() print '\n#-- input q to exit any key to continue' try: ch = str(raw_input()) except: ch = ''
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 好薇2024《兵哥哥》1:124K黄金母盘[WAV+CUE]
- 胡歌.2006-珍惜(EP)【步升大风】【FLAC分轨】
- 洪荣宏.2014-拼乎自己看【华特】【WAV+CUE】
- 伊能静.1999-从脆弱到勇敢1987-1996精选2CD【华纳】【WAV+CUE】
- 刘亮鹭《汽车DJ玩主》[WAV+CUE][1.1G]
- 张杰《最接近天堂的地方》天娱传媒[WAV+CUE][1.1G]
- 群星《2022年度发烧天碟》无损黑胶碟 2CD[WAV+CUE][1.4G]
- 罗文1983-罗文甄妮-射雕英雄传(纯银AMCD)[WAV+CUE]
- 群星《亚洲故事香港纯弦》雨果UPMAGCD2024[低速原抓WAV+CUE]
- 群星《经典咏流传》限量1:1母盘直刻[低速原抓WAV+CUE]
- 庾澄庆1993《老实情歌》福茂唱片[WAV+CUE][1G]
- 许巍《在别处》美卡首版[WAV+CUE][1G]
- 林子祥《单手拍掌》华纳香港版[WAV+CUE][1G]
- 郑秀文.1997-我们的主题曲【华纳】【WAV+CUE】
- 群星.2001-生命因爱动听电影原创音乐AVCD【MEDIA】【WAV+CUE】