iOS-面向协议编程

用工厂方法时,先定义了一个基类,在基类的声明中定义了一系列的方法,类实现里面并不需要实现,而是在子类里面实现的,需要的只是基类中的.h文件的方法声明。这个是不是和协议有点像,定义一个基协议,让各个工厂类都遵守这个基协议。我们就拿地图说事。百度地图和高德地图的视图都是继承的UIView,请看代码。
1>首先我们先定义2个基协议。

#import 
#import "ImapView.h"

@protocol IMapFactory 

- (id)getMapViewWithFrame:(CGRect)frame;

@end
#import 

@protocol ImapView 

- (instancetype)initWithFrame:(CGRect)frame;

- (UIView *)getMapView;

@end

第一个协议是用来生产一个遵守IMapFactory这个协议的工厂。第二个协议就是通过遵守IMapFactory协议的工厂来生产地图。

给每个第三方地图定义2个类,一个类是来生产地图工厂,另一个就是通过工厂来生产地图视图。

.h文件
#import 

#import "IMapFactory.h"

@interface BaiduMapFactory : NSObject 

@end

遵守了IMapFactory就能拿到协议里面的方法,从而可以返回一个遵守ImapView协议的地图视图。同样初始化方法也可以写在地图工厂里,从而做到瘦身程序入口方法

.m文件
#import "BaiduMapFactory.h"
#import "BaiduMapView.h"
#import //引入base相关所有的头文件
#import //引入地图功能所有的头文件

@interface BaiduMapFactory ()
@property (nonatomic,strong) BMKMapManager *mapManager;
@end

@implementation BaiduMapFactory

- (instancetype)init {

    if (self = [super init]) {
        _mapManager = [[BMKMapManager alloc] init];
        [_mapManager start:@"HBnGpGicUfd6SwSr5oCMre3asI29U0GG" generalDelegate:nil];
    }
    return self;
}

- (id)getMapViewWithFrame:(CGRect)frame {
    return [[BaiduMapView alloc] initWithFrame:frame];
}

@end

让地图视图这个类遵守ImapView这份协议。用来返回地图视图。

.h文件
#import 
#import "ImapView.h"

@interface BaiduMapView : UIView 

@end
.m文件
#import "BaiduMapView.h"
#import //引入base相关所有的头文件
#import //引入地图功能所有的头文件

@interface BaiduMapView ()
@property (nonatomic,strong) BMKMapView *mapView;
@end

@implementation BaiduMapView

- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
        _mapView = [[BMKMapView alloc] initWithFrame:frame];
    }
    return self;
}

- (UIView *)getMapView {

    return _mapView;
}
@end

等等,这个工厂谁来创建了,难道要在客户端去手动实例化工厂吗?no no no 这种设计原则太烂了。定义一个地图引擎用来返回工厂,而返回的工厂遵守IMapFactory协议就行。

.h文件
#import 
#import "IMapFactory.h"

typedef NS_ENUM(NSInteger, mapType) {
    baidu,
    gaode
};

@interface MapEngine : NSObject

- (id )getMapFactoryWithType:(mapType)type;
@end
.m文件
#import "MapEngine.h"
#import "BaiduMapFactory.h"
#import "GaodeMapFactory.h"

@implementation MapEngine

- (id )getMapFactoryWithType:(mapType)type {
    
    if (type == baidu) {
        return [[BaiduMapFactory alloc] init];
    } else {
    
        return [[GaodeMapFactory alloc] init];
    }
}
@end

那么客户端的代码就简单了,引擎->工厂->地图。

MapEngine *engine = [[MapEngine alloc] init];
id  factory = [engine getMapFactoryWithType:baidu];
id  mapView = [factory getMapViewWithFrame:self.view.frame];
[self.view addSubview:[mapView getMapView]];

高德地图也是一样,定义2个类,一个工厂,一个视图。分别遵守2个协议。切换地图时,只需要修改一个参数即可替换。
总结:面向协议就是充分利用了只要继承了协议,就能获取协议中所有的方法这个特点,和工厂方法有点类似。

你可能感兴趣的:(iOS-面向协议编程)