• 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

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

  • 相关阅读:
    window.location.href问题,点击,跳转到首页
    JS indexOf() lastIndexOf()与substring()截取字符串的区别
    原来的方法增加参数时,必须为新增的参数加个默认值
    Chrome不支持本地Ajax请求解决?
    Smarty中{literal}的使用详解
    windows不能在本地计算机启动apache
    Apache虚拟主机配置
    wamp环境网站根目录更改
    Java 读书笔记 (十三) for each 循环
    Java 读书笔记 (十二) Java Character 类
  • 原文地址:https://www.cnblogs.com/madpanda/p/4668819.html
Copyright © 2020-2023  润新知