iOS-面向協(xié)議編程

用工廠方法時(shí),先定義了一個(gè)基類,在基類的聲明中定義了一系列的方法,類實(shí)現(xiàn)里面并不需要實(shí)現(xiàn),而是在子類里面實(shí)現(xiàn)的,需要的只是基類中的.h文件的方法聲明。這個(gè)是不是和協(xié)議有點(diǎn)像,定義一個(gè)基協(xié)議,讓各個(gè)工廠類都遵守這個(gè)基協(xié)議。我們就拿地圖說事。百度地圖和高德地圖的視圖都是繼承的UIView,請(qǐng)看代碼。
1>首先我們先定義2個(gè)基協(xié)議。

#import <UIKit/UIKit.h>
#import "ImapView.h"

@protocol IMapFactory <NSObject>

- (id<ImapView>)getMapViewWithFrame:(CGRect)frame;

@end
#import <UIKit/UIKit.h>

@protocol ImapView <NSObject>

- (instancetype)initWithFrame:(CGRect)frame;

- (UIView *)getMapView;

@end

第一個(gè)協(xié)議是用來生產(chǎn)一個(gè)遵守IMapFactory這個(gè)協(xié)議的工廠。第二個(gè)協(xié)議就是通過遵守IMapFactory協(xié)議的工廠來生產(chǎn)地圖。

給每個(gè)第三方地圖定義2個(gè)類,一個(gè)類是來生產(chǎn)地圖工廠,另一個(gè)就是通過工廠來生產(chǎn)地圖視圖。

.h文件
#import <UIKit/UIKit.h>

#import "IMapFactory.h"

@interface BaiduMapFactory : NSObject <IMapFactory>

@end

遵守了IMapFactory就能拿到協(xié)議里面的方法,從而可以返回一個(gè)遵守ImapView協(xié)議的地圖視圖。同樣初始化方法也可以寫在地圖工廠里,從而做到瘦身程序入口方法

.m文件
#import "BaiduMapFactory.h"
#import "BaiduMapView.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相關(guān)所有的頭文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地圖功能所有的頭文件

@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<ImapView>)getMapViewWithFrame:(CGRect)frame {
    return [[BaiduMapView alloc] initWithFrame:frame];
}

@end

讓地圖視圖這個(gè)類遵守ImapView這份協(xié)議。用來返回地圖視圖。

.h文件
#import <UIKit/UIKit.h>
#import "ImapView.h"

@interface BaiduMapView : UIView <ImapView>

@end
.m文件
#import "BaiduMapView.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相關(guān)所有的頭文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地圖功能所有的頭文件

@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

等等,這個(gè)工廠誰來創(chuàng)建了,難道要在客戶端去手動(dòng)實(shí)例化工廠嗎?no no no 這種設(shè)計(jì)原則太爛了。定義一個(gè)地圖引擎用來返回工廠,而返回的工廠遵守IMapFactory協(xié)議就行。

.h文件
#import <Foundation/Foundation.h>
#import "IMapFactory.h"

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

@interface MapEngine : NSObject

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

@implementation MapEngine

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

那么客戶端的代碼就簡(jiǎn)單了,引擎->工廠->地圖。

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

高德地圖也是一樣,定義2個(gè)類,一個(gè)工廠,一個(gè)視圖。分別遵守2個(gè)協(xié)議。切換地圖時(shí),只需要修改一個(gè)參數(shù)即可替換。
總結(jié):面向協(xié)議就是充分利用了只要繼承了協(xié)議,就能獲取協(xié)議中所有的方法這個(gè)特點(diǎn),和工廠方法有點(diǎn)類似。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容