您的位置:首页 > 移动开发 > IOS开发

iOS设计模式(代码分析系列2:简单工厂模式)

2015-10-09 00:00 483 查看

iOS设计模式(代码分析系列2:简单工厂模式)

摘要简单工厂模式是工厂模式的一种

iOS设计模式优化简单工厂模式计算器示例

简单工厂模式示例代码下载地址,
1、简述
首先需要说明一下,简单工厂模式不属于23种GOF设计模式之一。它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式)。这里对简单工厂模式进行介绍,是为后面的工厂方法和抽象工厂模式做一个引子。
2、定义
“专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。”

世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例。
3、结构图



简要分析结构图:
ConcreteProduct1和ConcreteProduct2两个产品具有一个共同的父类IProject,简单工厂类为SimpleFactory,负责根据传入的不同参数来决定生产ConcreteProduct1还是ConcreteProduct2产品。
4、代码示例讲解
模拟一个使用计算器的场景:用户可以输入两个数和操作符号,然后得到结果,使用交互如下图所示,分别进行除运算和减运算,
(1)除运算示例



(2)减运算示例



一个新手,极有可能按照自己的初步思维逻辑,判断用户输入的运算符,然后将两个数字进行运算,当然还会加上必要的除数不为0的判断,那么点击运算Button,对应的事件可以如下面这样编写,
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32
-(IBAction)getResult:(id)sender{


//得到三个文本输入框的内容


NSString*strFirstNum=self.FirstNumTextField.text;


NSString*strSecondNum=self.SecondNumTextField.text;


NSString*strOperation=self.OperationTextField.text;


//进行运算操作


if
([strOperationisEqualToString:@
"+"
]){


NSLog(@
"+"
);


double
result=[strFirstNumdoubleValue]+[strSecondNumdoubleValue];


self.ResultTextField.text=[NSStringstringWithFormat:@
"%f"
,result];


}
else
if
([strOperationisEqualToString:@
"-"
]){


NSLog(@
"-"
);


double
result=[strFirstNumdoubleValue]-[strSecondNumdoubleValue];


self.ResultTextField.text=[NSStringstringWithFormat:@
"%f"
,result];


}
else
if
([strOperationisEqualToString:@
"*"
]){


NSLog(@
"*"
);


double
result=[strFirstNumdoubleValue]*[strSecondNumdoubleValue];


self.ResultTextField.text=[NSStringstringWithFormat:@
"%f"
,result];


}


else
if
([strOperationisEqualToString:@
"/"
]){


NSLog(@
"/"
);


//判断除数不能为0


if
([strSecondNumisEqualToString:@
"0"
]){


NSLog(@
"除数不能为0"
);


UIAlertView*tempAlert=[[UIAlertViewalloc]initWithTitle:@
"警告"
message:@
"除数不能为0"
delegate:nilcancelButtonTitle:@
"取消"
otherButtonTitles:nil];


[tempAlertshow];


}
else
{


double
result=[strFirstNumdoubleValue]/[strSecondNumdoubleValue];


self.ResultTextField.text=[NSStringstringWithFormat:@
"%f"
,result];


}


}

}
恩,这样写肯定能够实现功能。但是如果进行更多的运算,例如增加开平方、乘方运算,增加100种运算,那么是不是要增加100个elseif判断语句呢?如果这样去做每次都要去修改这部分代码,这样有悖于可扩展性原则。所以我们需要引入简单工厂模式,把运算给抽象出来,并且加入运算工厂用于接收用户的操作。

注释:这里我们把运算这个动作给抽象出来,当做一个对象,可能很多人觉得有点迷糊。我们知道,面向对象编程是不同于面向过程编程的,通常将一个事物给抽象成一个类,类具有属性和方法;那么我们也可以把一个动作进行抽象,例如此处的运算Operation,它具有两个属性(前一个操作数和后一个操作数),它具有的方法就是获取运算的结果。所以深入理解面向对象编程,还有很多的路要走。
那么此处我们可以抽象出一个UML图,如下所示,




与上面的UML结构图类似,这里再简单解释一下,加、减、乘、除四个运算符都继承自父类Operation,有两个属性和一个操作方法,这些加减乘除的对象并不是直接在ViewController中创建,而是根据输入操作符,由简单工厂OperationFactory来创建。
(1)创建一个协议OprationProtocol,由父类Operation来遵从该协议

?

1

2

3

4

5

6
/*


*操作方法协议接口


*/

@protocolOperationProtocol<NSObject>

-(
double
)getResult;

@end
(2)定义加减乘除操作的父类Operation
?

1

2

3

4

5

6

7

8
#importOperationProtocol.h

/*


*操作方法父类


*/

@interfaceOperation:NSObject<operationprotocol>

@property
double
firstNum;
//第一个操作数

@property
double
secondNum;
//第二个操作数

@end
(3)加减乘除实现类,此处以"加"举例说明,

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
//OperationAdd.h文件

#importOperation.h

/*


*加法实现类


*/

@interfaceOperationAdd:Operation

@end

//OperationAdd.m文件

#import"OperationAdd.h"

@implementationOperationAdd

-(
double
)getResult

{


double
result=0;


result=self.firstNum+self.secondNum;
//"+"是OperationAdd时候使用,"+-*/"分别对应"加减乘除"


return
result;

}

@end
(4)简单工厂类的代码,
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36
//OpeartionFactory.hfile

#importOperation.h

#importOperationAdd.h

#importOperationSub.h

#importOperationMultiply.h

#importOperationDivide.h

/*


*操作工厂类


*/

@interfaceOperationFactory:NSObject



//获得操作对象

+(Operation*)createOperate:(NSString*)operateStr;



@end

//OpeartionFactory.mfile

#import"OperationFactory.h"

@implementationOperationFactory

+(Operation*)createOperate:(NSString*)operateStr

{


Operation*oper=nil;


//根据不同的操作符,创建不同的操作对象,"+-*/"分别对应"加减乘除"


if
([operateStrisEqualToString:@
"+"
]){


oper=[[OperationAddalloc]init];


}
else
if
([operateStrisEqualToString:@
"-"
]){


oper=[[OperationSuballoc]init];


}
else
if
([operateStrisEqualToString:@
"*"
]){


oper=[[OperationMultiplyalloc]init];


}
else
if
([operateStrisEqualToString:@
"/"
]){


oper=[[OperationDividealloc]init];


}


return
oper;

}

@end
(5)客户端代码,在ViewController中使用OperationFactory

?

1

2

3

4

5

6

7

8

9
-(IBAction)clickingOperation:(id)sender{


NSString*strFirstNum=self.firstNumTextField.text;


NSString*strSecondNum=self.secondNumTextField.text;


Operation*oper;


oper=[OperationFactorycreateOperate:self.operationTextField.text];


oper.firstNum=[strFirstNumdoubleValue];


oper.secondNum=[strSecondNumdoubleValue];


self.resultTextField.text=[NSStringstringWithFormat:@%f,[opergetResult]];

}
这样的话ViewController中的代码看起来就简洁明了,而且易于扩展。
那么我们根据ViewController中的代码,分析一下使用思路,把操作类类比成一个容器,它有输入端(操作符号、第一个操作数、第二个操作数)和输出端(运算结果),如下图所示,



所以上面的代码将ViewController的TextField中的输入内容拿过来创建操作对象,并且把操作运算的逻辑放在了Operation及其子类中实现,然后将结果返回给ViewController,这样减少了ViewController的逻辑代码。
通过简单工厂模式的重构,我们就是闲了低耦合度的代码结构,做到了对外扩展开放,对修改关闭。如果再增加任何的操作方法,只需要继承操作方法父类,新建一个操作子类,并且在简单工厂类里面多添加一个elseif的判断即可。
五、优缺点
优点:简单工厂模式的优点是客户端可以直接消费产品,而不必关心具体产品的实现,消除了客户端直接创建产品对象的责任,实现了对责任的分割。
缺点是工厂类几种了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响,而且当产品类多结构复杂的时候,把所有创建工作放进一个工厂中来,回事后期程序的扩展较为困难。
通过优缺点的分析,我们可以再如下场景中使用简单工厂模式:
(1)工厂类负责创建的对象较少时;
(2)客户端只知道传入工厂类的参数,对于如何创建对象的逻辑不必关心时。
六、参考博客
(1)iOS设计模式浅析值简单工厂模式(SimpleFactory)
(2)设计模式深入学习iOS版(2)简单工厂模式
(3)计算机简单工厂模式示例代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: