Objective-C设计模式——适配器Adapter(接口适配)

适配器模式

适配器模式通俗来讲,其实就是对客户端添加新的类但却不修改客户端和新的类的接口。此时我们需要自己来实现适配,在适配器模式中有Target对象,即客户端所需要的接口对象,Adaptee对象,即需要适配的对象,中间需要Adapter对象来进行适配。简单来说,客户端要用某个类的接口,但是和客户端所用的通用接口不一致,此时就需要适配器来统一接口供客户端调用。适配器模式一般在后期维护客户端的时候才会用到,因为初期肯定不会出现设计接口不一致的问题(不过也可能是代码复用导致了不一致)。适配其有两种,一种是类适配器,一种是对象适配器。类适配器就是让适配器对象继承要被适配的对象,从而用子类来扩展新方法完成适配,而对象适配器就是持有需要适配的对象引用来自定义方法完成适配。

 

应用场景

1.已有类的接口与需求不一致。

2.想要一个可复用的类,该类能够同可能带有不兼容接口的其他类协作。

3.需要适配一个类的几个不同子类,可是让每一个子类去子类化一个类适配器又不现实,那么可以使用对象适配器(也叫委托)来适配其父类的接口。

 

类对象适配与对象适配器的区别

类适配器

只针对单一的具体Adaptee类,把Adaptee适配到Target。

易于重载Adaptee的行为,因为是通过直接的子类化进行的适配。

只有一个Adapter对象,无需额外的指针间接访问。

 

对象适配器

可以适配对个Adaptee以及其子类。

难以重载Adaptee的行为,需要借助于子类对象而不是Adaptee本身。

需要额外的指针以间接访问Adaptee并适配其行为。

 

iOS中的委托设计模式

对于委托模式,其实本身就是适配器。客户端就是iOS的框架类,Target就是代理协议,Adaptee就是Controller中的自定义类,Adapter就是实现协议的类。

比如说UITableView类,我们在控制器中写的对象是不可以直接和UITableView交流的,需要适配器,那么实现了Delegate的Controller就是一个适配器,UITableController本身就是客户端对象。

不过委托设计模式和适配器还是有一些区别的,委托对象同时会持有委托发起对象的引用,所以这里会有相会引用,这也是为什么delegate属性一般都是weak的原因。

 

Demo

Adaptee类

#import <Foundation/Foundation.h>

@interface Adaptee : NSObject

@property (nonatomic, strong)NSString *name;

-(void)sayName;

@end


#import "Adaptee.h"

@implementation Adaptee

-(id)init{

    self = [super init];
    if(self)
    {
        _name = @"adaptee target";
    }
    return self;
}

-(void)sayName{

    NSLog(@"%@",self.name);
    
}

@end

Adapter类

#import <Foundation/Foundation.h>
#import "Target.h"
#import "Adaptee.h"

@interface Adapter : NSObject<Target>

@property (nonatomic ,strong)Adaptee *adaptee;

@end


#import "Adapter.h"

@implementation Adapter

-(void)speakName
{
    [self.adaptee sayName];
}

@end

Target协议

#import <Foundation/Foundation.h>

@protocol Target <NSObject>

@required
-(void)speakName;

@end

客户端

        Adaptee *adaptee = [Adaptee new];
        Adapter *adapter = [Adapter new];
        adapter.adaptee = adaptee;
        id<Target> target = adapter;
        [target speakName];

运行结果

2015-07-22 22:01:16.032 Adapter[725:186663] adaptee target

例子可能举得不是很恰当,因为实际的客户端应该是一个类,这里主要是为了方便理解这样写。

你可能感兴趣的:(Objective-C)