下面来聊聊设计模式中的工厂模式,它又分为(工厂方法,简单工厂,抽象工厂),那么这3种又有什么区别呢,来,聊个5毛钱的。工厂模式是利用了面向对象3大特性之一——多态,父类指针指向子类对象这个特性。父类定义方法,子类实现。
一、工厂方法
第三方集成是iOS必备的一个技能吧,比如说,支付,地图。我们就拿地图说事吧,集成了百度地图,后面要改成高德地图。一般为了方便就把代码耦合在项目中了,虽然说代码量是很少,维护起来是很方便,但是我们要学的是思想。像下面这种把一些初始化方法放在didFinishLaunchingWithOptions中,第三方集成多了显得臃肿,代码难看。
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_mapManager = [[BMKMapManager alloc]init];
[_mapManager start:@"在此处输入您的授权Key" generalDelegate:nil];
return YES;
}
1>分析,发现百度地图BMKMapView是继承的UIView,高德地图MAMapView也是继承了UIView,是不是可以做文章了???
@interface BMKMapView : UIView
@interface MAMapView : UIView
接下来就用工厂方法来处理地图,一行代码切换地图。首先我们先定义一个父类IMapFactory,定义其方法。
.h文件
#import <UIKit/UIKit.h>
@interface IMapFactory : UIView
- (id)getMapFactoryWithFrame:(CGRect)frame;
@end
.m文件
#import "IMapFactory.h"
@implementation IMapFactory
- (id)getMapFactoryWithFrame:(CGRect)frame {
return nil;
}
@end
2>创建两个子类BaiduMapFactory和GaodeMapFactory继承IMapFactory,在子类中实现其父类的方法。
- (id)getMapFactoryWithFrame:(CGRect)frame {
_mapManager = [[BMKMapManager alloc] init];
[_mapManager start:@"HBnGpGicUfd6SwSr5oCMre3asI29U0GG" generalDelegate:nil];
_mapView = [[BMKMapView alloc] initWithFrame:frame];
return _mapView;
}
这里可以将百度地图的初始化代码写在这里,瘦身didFinishLaunchingWithOptions这个程序入口,程序设计有一个很好的原则,我需要用你,你内部怎么定义的我不管,我只管用。高德地图也是一样实现父类的方法。
3>接下来终于要用到了地图这个功能了。
IMapFactory *mapFactory = [[BaiduMapFactory alloc] getMapFactoryWithFrame:self.view.bounds];
[self.view addSubview:mapFactory];
你没有看错2行代码就能实现地图功能,以后要修改地图,直接将BaiduMapFactory 换成GaodeMapFactory即可。
4>工厂方法总结:定义一个用于创建对象的接口,是由子类决定实例化那种对象。与父类无关。
二、简单工厂
简单工厂相比工厂方法父类多了一些逻辑的判断,父类根据一些条件作出相应的判断来取出子类。,客户端给工厂基类条件,基类通过判断来实例化对应的子类。
IMapFactory *mapFactory = [[IMapFactory alloc] getMapFactoryWithFrame:self.view.bounds type:baidu];
[self.view addSubview:mapFactory];
基类的条件判断
#import "IMapFactory.h"
#import "BaiduMapFactory.h"
#import "GaodeMapFactory.h"
@implementation IMapFactory
- (id)getMapFactoryWithFrame:(CGRect)frame type:(mapType)type {
if (type == baidu) {
return [[BaiduMapFactory alloc] getMapFactoryWithFrame:frame type:type];
} else {
return [[GaodeMapFactory alloc] getMapFactoryWithFrame:frame type:type];
}
}
@end
优点:在客户端,就可以不用导入子类的头文件了,所有的操作都是客户端通过条件,让基类自己来实例化子对象。