最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
iOS设计模式 简单工厂模式 实例代码分析
时间:2015-08-09 编辑:简简单单 来源:一聚教程网
1、简述
首先需要说明一下,简单工厂模式不属于23种GOF设计模式之一。它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式)。这里对简单工厂模式进行介绍,是为后面的工厂方法和抽象工厂模式做一个引子。
2、定义
“专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。”
世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例。
3、结构图
简要分析结构图:
ConcreteProduct1和ConcreteProduct2两个产品具有一个共同的父类IProject,简单工厂类为SimpleFactory,负责根据传入的不同参数来决定生产ConcreteProduct1还是ConcreteProduct2产品。
4、代码示例讲解
模拟一个使用计算器的场景:用户可以输入两个数和操作符号,然后得到结果,使用交互如下图所示,分别进行除运算和减运算,
(1)除运算示例
(2)减运算示例
一个新手,极有可能按照自己的初步思维逻辑,判断用户输入的运算符,然后将两个数字进行运算,当然还会加上必要的除数不为0的判断,那么点击运算Button,对应的事件可以如下面这样编写,
- (IBAction)getResult:(id)sender { //得到三个文本输入框的内容 NSString* strFirstNum = self.FirstNumTextField.text; NSString* strSecondNum = self.SecondNumTextField.text; NSString* strOperation = self.OperationTextField.text; //进行运算操作 if ([strOperation isEqualToString:@"+"]) { NSLog(@"+"); double result = [strFirstNum doubleValue]+[strSecondNum doubleValue]; self.ResultTextField.text = [NSString stringWithFormat:@"%f",result]; }else if([strOperation isEqualToString:@"-"]){ NSLog(@"-"); double result = [strFirstNum doubleValue]-[strSecondNum doubleValue]; self.ResultTextField.text = [NSString stringWithFormat:@"%f",result]; }else if([strOperation isEqualToString:@"*"]){ NSLog(@"*"); double result = [strFirstNum doubleValue]*[strSecondNum doubleValue]; self.ResultTextField.text = [NSString stringWithFormat:@"%f",result]; } else if([strOperation isEqualToString:@"/"]){ NSLog(@"/"); //判断除数不能为0 if ([strSecondNum isEqualToString:@"0"]) { NSLog(@"除数不能为0"); UIAlertView* tempAlert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"除数不能为0" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil]; [tempAlert show]; }else{ double result = [strFirstNum doubleValue]/[strSecondNum doubleValue]; self.ResultTextField.text = [NSString stringWithFormat:@"%f",result]; } } }
恩,这样写肯定能够实现功能。但是如果进行更多的运算,例如增加开平方、乘方运算,增加100种运算,那么是不是要增加100个else if判断语句呢?如果这样去做每次都要去修改这部分代码,这样有悖于可扩展性原则。所以我们需要引入简单工厂模式,把运算给抽象出来,并且加入运算工厂用于接收用户的操作。
注释:这里我们把运算这个动作给抽象出来,当做一个对象,可能很多人觉得有点迷糊。我们知道,面向对象编程是不同于面向过程编程的,通常将一个事物给抽象成一个类,类具有属性和方法;那么我们也可以把一个动作进行抽象,例如此处的运算Operation,它具有两个属性(前一个操作数和后一个操作数),它具有的方法就是获取运算的结果。所以深入理解面向对象编程,还有很多的路要走。
那么此处我们可以抽象出一个UML图,如下所示,
与上面的UML结构图类似,这里再简单解释一下,加、减、乘、除四个运算符都继承自父类Operation,有两个属性和一个操作方法,这些加减乘除的对象并不是直接在ViewController中创建,而是根据输入操作符,由简单工厂OperationFactory来创建。
(1)创建一个协议OprationProtocol,由父类Operation来遵从该协议
/* * 操作方法协议接口 */ @protocol OperationProtocol-(double)getResult; @end
(2)定义加减乘除操作的父类Operation
#import OperationProtocol.h /* * 操作方法父类 */ @interface Operation : NSObject@property double firstNum;//第一个操作数 @property double secondNum;//第二个操作数 @end
(3)加减乘除实现类,此处以"加"举例说明,
//OperationAdd.h文件 #import Operation.h /* * 加法实现类 */ @interface OperationAdd : Operation @end //OperationAdd.m文件 #import "OperationAdd.h" @implementation OperationAdd -(double)getResult { double result = 0; result = self.firstNum+self.secondNum;//"+"是OperationAdd时候使用,"+-*/"分别对应"加减乘除" return result; } @end
(4)简单工厂类的代码,
//OpeartionFactory.h file #import Operation.h #import OperationAdd.h #import OperationSub.h #import OperationMultiply.h #import OperationDivide.h /* * 操作工厂类 */ @interface OperationFactory : NSObject //获得操作对象 +(Operation*)createOperate:(NSString*)operateStr; @end //OpeartionFactory.m file #import "OperationFactory.h" @implementation OperationFactory +(Operation*)createOperate:(NSString*)operateStr { Operation* oper = nil; //根据不同的操作符,创建不同的操作对象,"+-*/"分别对应"加减乘除" if ([operateStr isEqualToString:@"+"]) { oper = [[OperationAdd alloc] init]; }else if ([operateStr isEqualToString:@"-"]){ oper = [[OperationSub alloc] init]; }else if ([operateStr isEqualToString:@"*"]){ oper = [[OperationMultiply alloc] init]; }else if ([operateStr isEqualToString:@"/"]){ oper = [[OperationDivide alloc] init]; } return oper; } @end
(5)客户端代码,在ViewController中使用OperationFactory
- (IBAction)clickingOperation:(id)sender { NSString* strFirstNum = self.firstNumTextField.text; NSString* strSecondNum = self.secondNumTextField.text; Operation* oper; oper = [OperationFactory createOperate:self.operationTextField.text]; oper.firstNum = [strFirstNum doubleValue]; oper.secondNum = [strSecondNum doubleValue]; self.resultTextField.text = [NSString stringWithFormat:@%f,[oper getResult]]; }
这样的话ViewController中的代码看起来就简洁明了,而且易于扩展。
那么我们根据ViewController中的代码,分析一下使用思路,把操作类类比成一个容器,它有输入端(操作符号、第一个操作数、第二个操作数)和输出端(运算结果),如下图所示,
所以上面的代码将ViewController的TextField中的输入内容拿过来创建操作对象,并且把操作运算的逻辑放在了Operation及其子类中实现,然后将结果返回给ViewController,这样减少了ViewController的逻辑代码。
通过简单工厂模式的重构,我们就是闲了低耦合度的代码结构,做到了对外扩展开放,对修改关闭。如果再增加任何的操作方法,只需要继承操作方法父类,新建一个操作子类,并且在简单工厂类里面多添加一个else if的判断即可。
五、优缺点
优点:简单工厂模式的优点是客户端可以直接消费产品,而不必关心具体产品的实现,消除了客户端直接创建产品对象的责任,实现了对责任的分割。
缺点是工厂类几种了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响,而且当产品类多结构复杂的时候,把所有创建工作放进一个工厂中来,回事后期程序的扩展较为困难。
通过优缺点的分析,我们可以再如下场景中使用简单工厂模式:
(1)工厂类负责创建的对象较少时;
(2)客户端只知道传入工厂类的参数,对于如何创建对象的逻辑不必关心时。
设计模式深入学习IOS版 简单工厂模式
我们总说面向对象要有可维护性,可扩展性,可复用性。今天我们就来学习一种简单地设计模式--简单工厂模式(FACTORY)。通过面向对象的封装,继承和多态来降低程序的耦合度。下面就让我们来深入学习这个模式。
详述
工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。
我们来看一个简单的例子:一个有关计算器的例子,用户可以输入两个数和操作符号,然后得到结果,普通的思路的代码实例:
//进行运算操作 if ([strOperation isEqualToString:@+]) { NSLog(@+); double result = [strFirstNum doubleValue]+[strSecondNum doubleValue]; self.ResultTextField.text = [NSStringstringWithFormat:@%f,result]; }else if([strOperationisEqualToString:@-]){ NSLog(@-); double result = [strFirstNum doubleValue]-[strSecondNum doubleValue]; self.ResultTextField.text = [NSStringstringWithFormat:@%f,result]; }else if([strOperationisEqualToString:@*]){ NSLog(@*); double result = [strFirstNum doubleValue]*[strSecondNum doubleValue]; self.ResultTextField.text = [NSStringstringWithFormat:@%f,result]; } else if([strOperationisEqualToString:@/]){ NSLog(@/); //判断除数不能为0 if ([strSecondNum isEqualToString:@0]) { NSLog(@除数不能为0); UIAlertView* tempAlert = [[UIAlertViewalloc] initWithTitle:@警告message:@除数不能为0 delegate:nilcancelButtonTitle:@取消 otherButtonTitles:nil]; [tempAlert show]; }else{ double result = [strFirstNum doubleValue]/[strSecondNum doubleValue]; self.ResultTextField.text = [NSStringstringWithFormat:@%f,result]; } }
上面代码确实可以实现这个功能,但是我们却没有考虑到:如果以后需要提供开平方运算,乘方运算扩展时候,改如何做呢?直接加个if else?如果加入了100种运算呢?如果这样去做是不是每次都要去改这部分代码,这样有悖我们可扩展性原则。所以我们需要引入简单工厂模式,把运算给抽象出来,并且加入运算工厂用于接收用户的操作,简单工厂方法代码:
UML图:
操作方法协议接口:
#import /*! * 操作方法协议接口 * * @since V1.0 */ @protocol OperationProtocol -(double)getResult; @end
操作方法父类:
#import #import OperationProtocol.h /*! * 操作方法父类 * * @since V1.0 */ @interface Operation : NSObject @property double firstNum;//第一个操作数 @property double secondNum;//第二个操作数 @end
加法实现类:
#import Operation.h /*! * 加法实现类 * * @since V1.0 */ @interface OperationAdd : Operation @end
操作工厂类:
#import #import Operation.h #import OperationAdd.h #import OperationSub.h #import OperationMultiply.h #import OperationDivide.h /*! * 操作工厂类 * * @since V1.0 */ @interface OperationFactory : NSObject //获得操作对象 +(Operation*)createOperate:(NSString*)operateStr; @end
客户端代码:
- (IBAction)clickingOperation:(id)sender { NSString* strFirstNum = self.firstNumTextField.text; NSString* strSecondNum = self.secondNumTextField.text; Operation* oper; oper = [OperationFactory createOperate:self.operationTextField.text]; oper.firstNum = [strFirstNum doubleValue]; oper.secondNum = [strSecondNum doubleValue]; self.resultTextField.text = [NSString stringWithFormat:@%f,[oper getResult]]; }
通过简单工厂模式的重构,这样我们就实现了低耦合度的代码结构,做到了对扩展开放,对修改关闭。如果再增加任何的操作方法,只需要继承操作方法父类,新建一个操作子类,并且在工厂方法里面多加一个if else的判断即可。怎么样很简单吧
相关文章
- sora软件价格介绍 02-22
- sora官网入口地址一览 02-22
- Sora生成的视频使用教程 02-22
- 《梦幻西游》元宵灯谜线索答案大全2024 02-22
- 《原神》有朋自远方来第一天通关攻略 02-22
- 《苏醒之路》四个结局达成攻略 02-22