#適配器模式(Adapter Pattern)
##簡介
在設計模式中,適配器模式有時候也稱包裝樣式或者包裝(wrapper)。將一個類的接口轉接成用戶所期待的。一個適配使得因接口不兼容而不能在一起工作的類工作在一起,做法是將類自己的接口包裹在一個已存在的類中。
適配器模式包含兩種,一種是類適配器,另一種是對象適配器。`類適配器`是通過類的繼承實現的適配,而`對象適配器`是通過對象間的關聯關系,組合關系實現的適配。二者在實際項目中都會經常用到,由于對象適配器是通過類間的關聯關系進行耦合的,因此在設計時就可以做到比較靈活,而類適配器就只能通過覆寫源角色的方法進行拓展,在實際項目中,對象適配器使用到的場景相對較多。在iOS開發中也推薦多使用組合關系,而盡量減少繼承關系,這是一種很好的編程習慣,因此我在這里只介紹對象適配器,想了解更多的關于類適配器的話,請自行Google之。
```
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
將一個類的接口變成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。
```
##簡例
###適配器模式說明
* Target目標角色 該角色定義把其他類轉換為何種接口,也就是我們的期望接口。
* Adaptee源角色 你想把“誰”轉換成目標角色,這個“誰”就是源角色,它是已經存在的、運行良好的類或對象。
* Adapter適配器角色 適配器模式的核心角色,其他兩個角色都是已經存在的角色,而適配器角色是需要新建立的,他的職責非常簡單:把源角色轉換為目標角色。
###適配器模式優點
* 適配器模式可以讓兩個沒有任何關系的類在一起運行,只要適配器這個角色能夠搞定他們就成。
* 增加了類的透明性。我們訪問的是目標角色,但是實現卻在源角色里。
* 提高了類的復用度。源角色在原有系統中還是可以正常使用的。
* 靈活性非常好。不想要適配器時,刪掉這個適配器就好了,其他代碼不用改。
Target
```
#import <Foundation/Foundation.h>
@protocol Target <NSObject>
- (void)userExpectInterface;
@end
```
Adaptee
```
#import <Foundation/Foundation.h>
@interface Adaptee : NSObject
- (void)doSometing;
@end
@implementation Adaptee
- (void)doSometing
{
NSLog(@"adaptee doing something!");
}
@end
```
Adapter
```
#import "Target.h"
#import "Adaptee.h"
@interface Adapter : NSObject<Target>
@property (strong, nonatomic) Adaptee *adaptee;
- (id)initWithAdaptee:(Adaptee *)adaptee;
@end
@implementation Adapter
@synthesize adaptee = _adaptee;
- (id)initWithAdaptee:(Adaptee *)adaptee
{
if (self = [super init]) {
_adaptee = adaptee;
}
return self;
}
- (void)userExpectInterface
{
[self.adaptee doSometing];
}
@end
```
main
```
#import <Foundation/Foundation.h>
#import "Adapter.h"
#import "Adaptee.h"
#import "Target.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Adaptee *adaptee = [[Adaptee alloc]init];
id<Target> object = [[Adapter alloc]initWithAdaptee:adaptee];
[object userExpectInterface];
}
return 0;
}
```
何時用適配器模式?兩個類所做的事情相同或者相似,但是具有不同的接口時要使用它。 客戶端代碼可以統一調用接口就行了,這樣應該可以更簡單,更直接,更緊湊。***在雙方都不太容易修改的時候再食用適配器模式適配。***