您的位置:首页 > 其它

设计模式深入浅出(四)接口适配——适配器

2017-10-12 21:50 489 查看
适配器模式可以说是一个典型的接口适配模式。

一个现实中的例子

现在让我设想这么一个问题,如何让别人写好的已有的类接口,无缝的融合到我们自己的工程中?前提是,你无法获取到别人的源代码,也就是你不能够修改别人的代码。

举一个我们APP中的例子:

我们的APP是一款类似于云盘文件管理系统的软件。它能够接入GoogleDrive,OneDrive,Dropbox等第三方云盘系统。

当然,接入第三方云盘,自然使用的是第三方提供的SDK。

在我们的APP中,所用的云盘文件,均是抽象为NXFileBase类型的。而第三方SDK的文件类型则各有不同,如GoogleDrive的文件类型可能就是GTLDriveFile之类。

同时,不同云盘SDK获取文件列表,下载文件等操作的接口也不尽相同。

这就面临一个问题:

接口的异构性导致了接口间的不匹配。

就像是我们那国内的充电器插头到美国一样,你根本没法用,因为插头规格标准是一样的。

我们的做法是,为所有的云盘SDK添加一层封装,比如GoogleDriver,我们将GoogleDrive的SDK封装在NXGoogleDrive中,而这层封装符合协议NXServiceOperation。

代码如下:

@class NXFileBase;
@protocol NXServiceOperation <NSObject>

@required -(BOOL) getFiles:(NXFileBase*)folder;
@required -(BOOL) getAllFilesInFolder:(NXFileBase *) folder;
@required -(BOOL) cancelGetFiles:(NXFileBase*)folder;

@required -(BOOL) downloadFile:(NXFileBase*)file;
@required -(BOOL) cancelDownloadFile:(NXFileBase*)file;

@required -(BOOL) deleteFileItem:(NXFileBase*)file;
@required -(BOOL) addFolder:(NSString *)folderName toPath:(NXFileBase *)parentFolder;
...
@end

@interface NXGoogleDrive : NSObject<NXServiceOperation>
- (id) initWithUserId: (NSString *)userId repoModel:(NXRepositoryModel *)repoModel;
@end

// NXGoogleDrive内部实现会调用GoogleDrive 的SDK:
@implementation NXGoogleDrive

- (BOOL) getFiles:(NXFileBase *)folder {
if (!folder || ![folder isKindOfClass:[NXFolder class]]) {
return NO;
}
if([folder isRoot]) {
folder.fullPath = @"/";
folder.fullServicePath = kKeyGoogleDriveRoot;
}

// 调用GoogleSDK
GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
query.q = [NSString stringWithFormat:@"trashed = false and '%@' IN parents", folder.fullServicePath];
_driveService.shouldFetchNextPages = YES;
GTLServiceTicket *fileTicket = [_driveService executeQuery:query delegate:self didFinishSelector:@selector(getFilesFinishedwithTicket:fileList:error:)];
fileTicket.properties = [NSDictionary dictionaryWithObjectsAndKeys:folder, kKeyGetFiles, nil];
if (fileTicket) {
[_listFilesTickets setObject:fileTicket forKey:folder.fullServicePath];
}
return  YES;
}

@end


同样,对于OneDrive,DropBox我们也做了对应的封装为:NXOneDrive,NXDropBox,它们同样遵循NXServiceOperation协议。

这样,UML图为



在这里,符合NXServiceOperation协议的NXGoogleDrive,NXOneDrive,NXDropBox相当于对第三方SDK做了一层适配,让他们能够无缝的集成与我们的APP中。

这就是适配器模式的典型应用。

适配器模式的定义为:

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。《设计模式》

适配器模式的实现由两种方案:

适配器模式的两种实现

对象组合

实现同我们上面的例子,将被适配方Adaptee作为一个成员放在适配器(Adapter)里面。Client调用Adapter接口,而Adapter内部调用Adaptee相应接口做具体实现。



多重继承

多重继承就是让Adapter继承Target,使之能够取得与Target相同的接口供Client调用,同时,继承Adaptee,使Adapter的接口实现能够调用Adaptee的方法,同时能够重写Adaptee方法,这是采用多重继承与对象组合的方式实现适配器模式最大的不同。

对于OC语言来说,不支持多继承,我们可以用Adapter遵循Target协议,同时继承Adaptee类来实现。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式