為何使用介面卡?
直接賦值的缺點
最簡單明瞭就是直接寫一個示例來說名
製作一張卡片:
對卡片的資料直接賦值:
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 |
#import "ViewController.h" #import "BusinessCard.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.name = @"姓名"; card.color = [UIColor blueColor]; card.phoneNumber = @"電話"; card.center = self.view.center; [self.view addSubview:card]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end |
執行結果:
非常簡單的一個示例,這基本上就是我們以前經常使用的一種方法直接賦值,這種的缺點,其實很簡單,就是耦合性太強了,簡簡單單的移除更改,可能就會造成很多地方進行更改。現在看起來很簡單就更改,但是如果我們的資料很多很多呢?
因此我們現在簡單的來改進一下,設計一個model。並且在BusinessCard新增如下程式碼:
1 2 3 4 5 6 7 8 9 10 |
/** * 初始化資料 * * @param model BusinessCard */ -(void)loadDataWithModel:(Model *)model{ self.name = model.name; self.phoneNumber = model.phoneNumber; self.line = model.lineColor; } |
ViewController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib Model *model = [[Model alloc] initWithName:@"lastdays" phoneNumber:@"158******1111" lineColor:[UIColor blueColor]]; BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.center = self.view.center; [card loadDataWithModel:model]; [self.view addSubview:card]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end |
這樣就降低了一些耦合性,這就是以物件形式賦值。
但是我們現在來闡述一個很致命的問題,那就是如果我們來了一個新的Model資料型別,其中的UIcolor是二進位制形的。跟我們原來處理的資料型別不符合?這個時候怎麼辦?
其實解決方案很簡單,這也就是上面提到過的,電源介面卡原理。
使用介面卡模型
電源有輸入和輸出,當然我們先來構建介面卡
CardAdapterProtocol:
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @protocol CardAdapterProtocol <NSObject> - (NSString *)name; - (UIColor *)lineColor; - (NSString *)phoneNumber; @end |
CardAdapter:
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 37 38 39 40 41 |
#import <Foundation/Foundation.h> #import "CardAdapterProtocol.h" #import <UIKit/UIKit.h> @interface CardAdapter : NSObject<CardAdapterProtocol> /** * 建立輸入關係 */ @property(nonatomic,weak) id data; /** * 與輸入物件建立聯絡 * * @param data 輸入的物件 * * @return 當前例項物件 */ - (instancetype)initWithModel:(id)data; @end ``` ``` bash #import "CardAdapter.h" @implementation CardAdapter - (NSString *)name{ return nil; } - (UIColor *)lineColor{ return nil; } - (NSString *)phoneNumber{ return nil; } @end |
這裡我們構建了CardAdapterProtocol協議,以及抽象類CardAdapter,接下來就是建立ModelCardAdapter,這就是針對Model構建的介面卡,然後覆蓋內部方法進行重寫。
這裡需要做一下說明CardAdapter中通過initWithModel建立與Model的輸入關係,就是我們在國內用充電器給手機充電,CardAdapter與Model的關係就是充電器跟220V電壓的關係。
接下來就該建立充電器跟手機的關係了,這裡面相當於構建CardAdapter和View的關係。
BusinessCard
1 2 3 4 5 6 7 8 9 10 |
/** * 初始化卡片資料 * * @param model BusinessCard */ -(void)loadDataWithModel:(id<CardAdapterProtocol>)data{ self.name = [data name]; self.phoneNumber = [data phoneNumber]; self.line = [data lineColor]; } |
這樣,我們基本上就完成了構建,測試:
ViewController:
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 |
#import "ViewController.h" #import "BusinessCard.h" #import "Model.h" #import "ModelCardAdapter.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Model *model = [[Model alloc] initWithName:@"lastdays" phoneNumber:@"158******1111" lineColor:[UIColor blueColor]]; //建立充電器跟電源關係 CardAdapter *cardAdapter = [[ModelCardAdapter alloc] initWithModel:model]; BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.center = self.view.center; //建立手機跟充電器關係 [card loadDataWithModel:cardAdapter]; [self.view addSubview:card]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end |
測試結果:
以上我們使用的就是類介面卡,當然還有一種叫做物件介面卡,就是說無論我們是220V,還是100V,用這一個充電器都能給手機充電。這種如何實現?簡單的說就是我們可以構建一個Adapter繼承CardAdapter,簡單的舉個例子
Adapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
- (NSString *)name { NSString *name = nil; if ([self.data isMemberOfClass:[Model class]]) { Model *model = self.data; name = model.name; } else if ([self.data isMemberOfClass:[NewCardModel class]]) { NewCardModel *model = self.data; name = model.name; } return name; } |
根絕物件型別進行判斷返回哪種處理結果。這種其實並不推薦,因為什麼?因為現在的資料模型比較少,如果有10個,20個資料模型,那這個類到最好會非常的臃腫,並不方便我們維護。
總結
優點
優點顯而易見,就是讓介面卡可以讓我們的View更加強大,可以適配不同的資料,降低我們的耦合性
缺點
其實在程式碼中就可以看出來,一個簡單賦值的東西,用了這麼多東西,比較麻煩,有的時候是很繁瑣的。但是呢?話又說回來,我們如果做了一個很牛的控制元件,為了提高它的通用性,加一個介面卡會更好一些。 當我們的程式碼能力增加。但是呢? 這同樣也是一個缺點,那就是程式碼的可讀性不好。這點的權衡就靠自己來衡量,雖然麻煩一些,但是確實能夠提高擴充套件性。