美文网首页女程序猿iOS-设计模式
iOS架构设计模式之适配器模式

iOS架构设计模式之适配器模式

作者: meryin | 来源:发表于2018-08-01 16:03 被阅读6次

    一 基本定义

    Demo

    1. 什么是适配器模式
      定义:适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。
      第一点:将一个原始接口转成客户端需要的接口
            原始接口--相当于:Adaptee
            客户端需要接口(调用者)---相当于:Target
      第二点:原始接口不兼容现在新的接口,将他们两个可以一起工作
      一起工作需要Adapter实现
    2. 应用场景
      第一点:接口不兼容
      第二点:可以重复使用的类,用于与一些彼此没有太大关联的一些类一起工作
      第三点:统一输出接口,输入端类型无法确定
    3. 角色划分
      角色一:适配器(核心)
      角色二:目标接口
      角色三:被适配者
      比如UITableView:
            角色一:适配器 ViewController 实现UITableView的两个delegate
            角色二:目标接口 UI界面,UITableViewCell画UI
            角色三:被适配者 model 将数据适配到UI上
      MVC模式下,ViewController作为适配器,会出现ViewController臃肿,可以利用适配器解决类的臃肿。

    二 原理案例-基本结构

    1. 类适配器

    第一种:类适配器
    金额转换->1000USA( Adaptee)->适配(Target)->人民币6500(Adapter)
          适配器:Adapter
                特点一:实现协议(目标接口) 特点二:适配器继承被适配者
          目标接口:Target (协议)
          被适配者:Adaptee
    Target:(协议)

    @protocol Target <NSObject>
    - (float)getRMB;
    @end
    

    被适配者:Adaptee 美元

    @implementation Adaptee
    - (float)getUSA{
        return  1000;
    }
    @end
    

    适配器:Adapter 人名币 继承Adaptee并遵守协议Target

    #import "Target.h"
    #import "Adaptee.h"
    
    @interface Adapter : Adaptee<Target>
    @end
    @implementation Adapter
    - (float)getRMB{
        return [self getUSA]*6.5;
    }
    @end
    
    2. 对象适配器

    金额转换->1000USA->适配->人民币6500
    适配器:ObjectAdapter
                特点一:实现协议(目标接口) 特点二:持有被适配者的引用

    // 对象适配器
    //特点一:实现协议
    //特点二:持有被适配者的引用
    #import <Foundation/Foundation.h>
    #import "Target.h"
    @interface ObjectAdapter : NSObject<Target>
    - (float)getRMB;
    @end
    
    @interface ObjectAdapter()
    @property (nonatomic,strong)Adaptee *adaptee;
    @end
    @implementation ObjectAdapter
    - (instancetype)init:(Adaptee*)adaptee
    {
        self = [super init];
        if (self) {
            self.adaptee = adaptee;
        }
        return self;
    }
    - (float)getRMB{
        return [self.adaptee getUSA]*6.5;
    }
    @end
    

    三 开发案例 UITableView (RxDataSource就是例子)

    原始代码:ViewController 臃肿重复代码
            角色一:适配器->ViewController(实现协议->两个delegate)
            角色二:目标接口->UI界面(抽象)->UITableView(Cell)
            角色三:被适配者->数据(UserModel…)
    优化代码,抽象以便复用:
            角色一:适配器->BaseAdapter 代替ViewController功能(实现UITableView的协议和持有被适配者即数据)

    // 适配器 替换ViewController去实现UITableView的协议
    //持有被适配者 即数据
    @interface BaseAdapter : NSObject<UITableViewDelegate, UITableViewDataSource>
    @property(nonatomic, strong) NSMutableArray* dataArray;//装数据
    @end
    
    @implementation BaseAdapter
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            self.dataArray = [NSMutableArray array];
        }
        return self;
    }
    
    //提供默认实现
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return 1;
    }
    
    //提供默认实现
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectio{
        return _dataArray.count;
    }
    
    //提供默认实现
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString * showUserInfoCellIdentifier = @"userInfoCell";
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:showUserInfoCellIdentifier];
        if (cell == nil){
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                          reuseIdentifier:showUserInfoCellIdentifier];
        }
        cell.textLabel.text = @"姓名";
        cell.detailTextLabel.text = @"Dream";
        return cell;
    }
    

    适配具体数据模型时可定制UserAdapter

    @interface UserAdapter : BaseAdapter
    
    @end
    - (instancetype)init{
        self = [super init];
        if (self) {
            //从网络获取数据
            [self.dataArray addObject:[[UserModel alloc] init:@"算悟空" tel:@"17785635421"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"猪八戒" tel:@"17785635431"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"唐僧" tel:@"17785635421"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"傻叉" tel:@"17785635421"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"算悟空" tel:@"17785635421"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"猪八戒" tel:@"17785635431"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"唐僧" tel:@"17785635421"]];
            [self.dataArray addObject:[[UserModel alloc] init:@"傻叉" tel:@"17785635421"]];
           
        }
        return self;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
        UserModel* user = [self.dataArray objectAtIndex:indexPath.row];
        cell.textLabel.text = user.name;
        cell.detailTextLabel.text = user.tel;
        return cell;
    }
    

           角色二:目标接口-> UITableView的协议
           角色三:被适配者->数据

    - (instancetype)init:(NSString *)name tel:(NSString*)tel
    {
        self = [super init];
        if (self) {
            self.name = name;
            self.tel = tel;
        }
        return self;
    }
    

    优化后的ViewController

    @property (nonatomic,strong)UITableView *tableView;
    @property (nonatomic,strong)UserAdapter  *adapter;
    @end
    
    @implementation ViewController //适配器
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        _adapter = [[UserAdapter alloc]init];
        _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
        [ self.view addSubview:_tableView];
        _tableView.delegate = _adapter;
        _tableView.dataSource = _adapter;
    }
    

    相关文章

      网友评论

        本文标题:iOS架构设计模式之适配器模式

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