设计模式一之:简单工厂模式
基于面向对象编程的语言有很多,Java ,c++ ,c# ,Objective-C等等,但设计模式都是相通的,本文仅以OC来阐述简单工厂模式的设计思路,希望能对大家有所启发。
面向对象编程的特点是,封装,继承,多态,这是老生常谈的话题,但是很多开发者在实际应用中,不自然的就会以面向过程的思路去想计算机应该怎么执行某个事件,下面我就举个例子来更加具体形象的去阐述本文的设计模式如何具体的去应用,帮助大家更好的理解面向对象编程。
先简单讲讲面向对象编程的这些特点有什么用处吧
举个例子,曹操在大江上喝酒的时候,即兴创作了一首诗“喝酒唱歌,人生真爽”,然后手底下的人马上找印刷匠在模板上刻字印刷下来,拿给曹操品鉴,曹操看了看自己创作的诗,感觉“喝酒”有瑕疵,改成“对酒”比较好,然后手底下的人马上找印刷匠重新刻模板,“对酒唱歌,人生真爽”,刻好后又拿给曹操看,曹操看了看之后,又觉得“唱歌”有点俗,改成“当歌”比较文雅一点,因为当时模板都是刻在一个板子上的,所以但凡有一点改动,全部都要重新刻。刻好“对酒当歌,人生真爽”拿给曹操看,顿时又觉得“人生真爽”太直白了,改成反问的“人生几何”更好,于是又一轮的重新刻录。
为了解决上面的问题,活字印刷术诞生了,每个字都是一个模板,如果不满意,只需要替换掉某个字就行了,被替换下来的字,以后想用还可以复用,因此,四大发明里,占一席之位的是活字印刷术而不是单纯的印刷术。
上面的例子跟产品经理或者客户频繁改需求是何等的相似,因此如果代码全写到一起,耦合度太高,往往一个对用户来说非常细小的改动,在代码上就像上手术台一样大改特改。所以,如果换成面向对象编程,用封装,继承,多态的方式,将所有的展示和逻辑分开,每个单元模块相对独立,那么,当需求变动,只需要改动相应一小部分代码,就能解决问题。
简单例子:写一个能加减乘除的计算器。
首先,看到这个命题,要先思考的是如何去实现一个计算器的功能吗?NO!!!
单纯写个方法去实现计算器的功能,很多刚学编程的小白都能写,但是直接写个方法出来,以后如果要加个平方的功能,根号的功能之类的怎么办。或者某个方程式需要加一些特殊的限制之类的怎么办。是不是要重新写个方法。要想到之后的可维护性,可扩展性,可复用性等问题,所以,大体思路如下:
1、首先要有一个总的运算类:Operation.声明两个变量和用枚举定义需求的运算类型。再留出一个接口getResult(),用于求值。
2、加减乘除等运算分别独立成一个类,继承自Operation.
3、每个类中各自重写getResult()方法。
4、在Operation类中,实现getResult()方法,根据运算类型,分别调用各种运算类。
如下
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger , OperationType) {
AddType = 0,
SubType,
MulType,
DivType
};
@interface ZYTOperation : NSObject
/** 参数一 */
@property (nonatomic , assign) CGFloat parameterOne;
/** 参数二 */
@property (nonatomic , assign) CGFloat parameterTwo;
+ (instancetype)CreatWithParameterOne:(CGFloat)One
withParameterTwo:(CGFloat)Two
withType:(OperationType)type;
- (CGFloat)getResult;
@end
#import "ZYTOperation.h"
#import "ZYTAdd.h"
#import "ZYTSubtraction.h"
#import "ZYTMultiplication.h"
#import "ZYTDivision.h"
@interface ZYTOperation()
/** 运算类型 */
@property (nonatomic , assign) OperationType type;
@end
@implementation ZYTOperation
static ZYTOperation *_operation;
+ (instancetype)CreatWithParameterOne:(CGFloat)One
withParameterTwo:(CGFloat)Two
withType:(OperationType)type {
_operation = [[ZYTOperation alloc] init];
_operation.parameterOne = One;
_operation.parameterTwo = Two;
_operation.type = type;
return _operation;
}
- (CGFloat)getResult {
switch (self.type) {
case AddType:return [[ZYTAdd CreatWithParameterOne:self.parameterOne withParameterTwo:self.parameterTwo withType:self.type] getResult];//加法
case SubType:return [[ZYTSubtraction CreatWithParameterOne:self.parameterOne withParameterTwo:self.parameterTwo withType:self.type] getResult];//减法
case MulType:return [[ZYTMultiplication CreatWithParameterOne:self.parameterOne withParameterTwo:self.parameterTwo withType:self.type] getResult];//乘法
case DivType:return [[ZYTDivision CreatWithParameterOne:self.parameterOne withParameterTwo:self.parameterTwo withType:self.type] getResult];//除法
default:return 0;
}
return 0;
}
@end