学习iOS设计模式第一章 适配器(Adapter)

作者: Ryan文濤 | 来源:发表于2016-01-30 13:20 被阅读1378次

    今天学习了iOS设计模式中的适配器模式,适配器有两种模式
    对象适配器模式
    -- 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
    类适配器模式
    -- 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。
    现在以一个例子来说明这种适配器的使用,首先在你的UI控件头文件里声明你需要用来适配的方法

     - (void)loadData:(id <BusinessCardAdapterProtocol>)data; 
    

    再到你的UI控件.m里面实现相应控件的属性赋值,然后新建一个BusinessCardAdapterProtocol协议,假如UI控件的需要外界设置下面这三种属性

     @property (nonatomic, copy) NSString *name;
     @property (nonatomic, copy) NSString *phoneNumber;
     @property (nonatomic, strong) UIColor  *lineColor;
    

    则在BusinessCardAdapterProtocol协议里面声明

    - (NSString *)name; 
    - (UIColor *)lineColor; 
    - (NSString *)phoneNumber;
    

    方法供实现,接下来再创建一个基本的适配器类BusinessCardAdapter,遵守BusinessCardAdapterProtocol协议,并在头文件里声明一个属性和一个构造方法

    @property (nonatomic, weak) id data; // 输入对象 
    
    - (instancetype)initWithData:(id)data; // 与输入对象建立联系
    

    在.m文件中实现如下代码

    - (instancetype)initWithData:(id)data{
        self = [super init];
        if (self) {
            self.data = data;
        }
        return self;
    }
    - (NSString *)name{
     
       return nil;
    }
    - (NSString *)phoneNumber{
        return nil;
    }
    - (UIColor *)lineColor{
        return nil;
    }
    

    现在新建一个模型文件叫作Model,属性如下

    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *phoneNumber;
    @property (nonatomic, strong) UIColor *lineColor;
    

    再创建一个用来适配Model类的适配器ModelAdapter继承自基类适配器BusinessCardAdapter,在.m文件里重载父类的方法如下

    #import "Model.h"
    #import "ModelAdapter.h"
    
    @implementation ModelAdapter
    
    - (instancetype)initWithData:(id)data{
        self = [super init];
        if (self) {
            self.data = data;
        }
        return self;
    }
    
    - (NSString *)name{
        Model *data = self.data;
        return data.name;
    }
    
    - (UIColor *)lineColor{
        Model *data = self.data;
        return data.lineColor;
    }
    
    - (NSString *)phoneNumber{
        Model *data = self.data;
        return data.phoneNumber;
    }
    
    @end
    

    这时候在我们的ViewController里面这样使用

    // 创建UI控件
    BusinessCardView *cardView = [[BusinessCardView alloc] initWithFrame:BUSINESS_FRAME]; cardView.center = self.view.center;
    [self.view addSubview:cardView];
    // 初始化模型   
    Model *model = [[Model alloc] init];
    model.name = @"CoderRyan";
    model.phoneNumber = @"188 - 8848 - 8848";
    model.lineColor = [UIColor redColor];
    // 与适配器连接
    BusinessCardAdapter *adapter = [[ModelAdapter alloc] initWithData:model];
    [cardView loadData:adapter];
    

    cmd+R运行,效果图如下

    Simulator Screen Shot 2016年1月30日 13.09.12.png

    假如现在有另外一个Model,需要适配,新建一个NewModel类,包含如下属性

    #import <Foundation/Foundation.h>
    
    @interface NewModel : NSObject
    
    @property (nonatomic, copy) NSString *name;
    
    @property (nonatomic, copy) NSString *hexColorString;
    
    @property (nonatomic, copy) NSString *phoneNumber;
    @end
    

    这时候,同样只需要新建一个继承自基类适配器BusinessCardAdapter,在.m文件里重载父类的方法如下

    #import "NewCardModelAdapter.h"
    #import "NewModel.h"
    @implementation NewCardModelAdapter
    
    - (instancetype)initWithData:(id)data
    {
        self = [super init];
        if (self) {
            self.data = data;
        }
        return self;
    }
    
    - (NSString *)name{
        NewModel *model = self.data;
        return model.name;
    }
    
    - (NSString *)phoneNumber{
        NewModel *model = self.data;
        return model.phoneNumber;
    }
    
    - (UIColor *)lineColor{
        NewModel *model = self.data;
        // TODO
        if ([model.hexColorString isEqualToString:@"black"]) {
            return [UIColor blackColor];
        } else {
            return [UIColor redColor];
        }
    }
    
    @end
    

    如果这时候想要在VC里面用新的适配器,只需要

    // 与适配器连接
    Model *model = [[Model alloc] init];
    model.name = @"CoderRyan";
    model.phoneNumber = @"188 - 8848 - 8848";
    model.lineColor = [UIColor redColor];
    
    BusinessCardAdapter *adapter = [[ModelAdapter alloc] initWithData:model];
    [cardView loadData:adapter];
    

    更改成

    NewModel *newModel = [[NewModel alloc] init];
    newModel.name = @"CoderRyan";
    newModel.phoneNumber = @"188 - 8848 -8848";
    newModel.hexColorString = @"black";
    
    BusinessCardAdapter *adapter = [[NewCardModelAdapter alloc] initWithData:newModel];
    [cardView loadData:adapter];
    

    即可.
    总结来说,就是在UI控件外部提供一个方法传入实现了协议的属性,外部根据一个模型来创建一个适配器,再通过与适配器连接.进行更新UI.
    优点:耦合度低,可以扩展多种适配的样式
    缺点:代码量多,文件多.对于新手可能不理解这种好处.
    以上是我对适配器模式的大致了解,上面的Demo是用极客学院的例子.如果有错漏之处,希望可以给我在下面评论留言给我指出,谢谢~

    相关文章

      网友评论

      • 星空丶:你好,我封装了一个静态库,但是我想在我的静态库中,调用另外一个静态库里的功能,应该怎么做呢?能加下QQ么?
      • xiari1991:问个问题:为什么中间加了一层ModelAdapter,不直接在BusinessCardAdapter中return data;这样不就可以loadData:(BusinessCardAdapter *)model;了吗

        栈溢出:@yf_js 这里有个多态的概念,父类对象调用子类。便于后期的一些扩展和维护,这样说你清楚了么
      • xiari1991:有demo吗
      • da27c260cc85:极客还讲这个呢?
        Ryan文濤:@啄木阳狐 恩,设计模式那里。

      本文标题:学习iOS设计模式第一章 适配器(Adapter)

      本文链接:https://www.haomeiwen.com/subject/xsojkttx.html