原文出處: Lastdays(@Lastday_s) 編程
很好奇,什麼是適配器,你們有沒有據說過電源適配器,其實原理都是同樣的,就是說咱們的iPhone手機,在中國,能夠用iPhone充電器給手機充電,都知道,中國的電壓是220V,對吧,咱們的iPhone額定輸入電壓是5V,其實這就是咱們適配器的功勞,並且,咱們的充電器在中國能用,固然若是咱們去了美國,沒過不是220V,難道咱們的手機就不能充電了嗎?固然確定不會,總結來講:在計算機編程中,適配器模式(有時候也稱包裝樣式或者包裝)將一個類的接口適配成用戶所期待的。一個適配容許一般由於接口不兼容而不能在一塊兒工做的類工做在一塊兒,作法是將類本身的接口包裹在一個已存在的類中。bash
最簡單明瞭就是直接寫一個示例來講名測試
製做一張卡片:atom
對卡片的數據直接賦值:spa
Objective-C.net
1設計 2orm 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 ()
@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添加以下代碼:
Objective-C
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:
Objective-C
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:
Objective-C
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:
Objective-C
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
Objective-C
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:
Objective-C
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
Objective-C
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更增強大,能夠適配不一樣的數據,下降咱們的耦合性
其實在代碼中就能夠看出來,一個簡單賦值的東西,用了這麼多東西,比較麻煩,有的時候是很繁瑣的。可是呢?話又說回來,咱們若是作了一個很牛的控件,爲了提升它的通用性,加一個適配器會更好一些。 當咱們的代碼能力增長。可是呢? 這一樣也是一個缺點,那就是代碼的可讀性很差。這點的權衡就靠本身來衡量,雖然麻煩一些,可是確實可以提升擴展性 QQ技術交流羣290551701