一,适配器的定义

  • 定义

    将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
  • 需求场景
    需要使用以前开发的“一些现存的对象”,但是新环境中要求的接口是这些现存对象所不满足的

二,适配器的结构图

  实现步骤:

  1. 定义接口,规范适配器的功能
  2. 定义适配器父类,便于各个子类的对于接口功能的实现
  3. 子类适配器继承父类适配器,实现子类下的接口功能
  4. 父类指针指向子类,调用子类的实现方法  

结构图:

三,代码示例

  • 接口协议

    • CellPhoneProtocol.h

      /**
      * @brief 面向接口编程,协议负责定义适配接口
      */
      @protocol CellPhoneProtocol <NSObject>
      - (NSString *)name;
      - (NSString *)playMusic;
      - (NSString *)playMovie;
  • 父类适配器
    • CellPhone.h

      @interface CellPhone : NSObject<CellPhoneProtocol>
      @property(nonatomic,strong) id data; //生成子类接受数据的变量
      - (instancetype)initWithData:(id)data; //便于子类接受数据源
      @end
    • CellPhone.m
      #import "CellPhone.h"
      
      @implementation CellPhone
      - (instancetype)initWithData:(id)data {
      if (self = [super init]) {
      self.data = data; //接受数据源数据
      }
      return self;
      } #pragma mark --Protocol Methods
      - (NSString *)name { //便于子类重写实现
      return nil;
      }
      - (NSString *)playMusic { //便于子类重写实现
      return nil;
      }
      - (NSString *)playMovie { //便于子类重写实现
      return nil;
      }
      @end
  • 子类适配器
    • Ios

      • Ios.h

        @interface Ios : CellPhone
        @end
      • Ios.m 
        @implementation Ios
        - (NSString *)name {
        IosModel *iosModel = (IosModel *)self.data;
        return iosModel.name;
        } - (NSString *)playMovie {
        IosModel *iosModel = (IosModel *)self.data;
        return iosModel.movieName;
        } - (NSString *)playMusic {
        IosModel *iosModel = (IosModel *)self.data;
        return iosModel.musicName;
        }
        @end
    • Android
      • Android.h

        @interface Android : CellPhone
        @enAndroid.m
      • Android.m
      • @implementation Android
        - (NSString *)name {
        AnroidModel *andriodModel = (AnroidModel *)self.data;
        return andriodModel.name;
        }
        - (NSString *)playMovie {
        AnroidModel *andriodModel = (AnroidModel *)self.data;
        return andriodModel.movieName;
        }
        - (NSString *)playMusic {
        AnroidModel *andriodModel = (AnroidModel *)self.data;
        return andriodModel.musicName;
        }
        @end
    • WPhone
      • WPhone.h

        @interface WPhone : CellPhone
        @enWPhone.m
      • WPhone.m
      • @implementation WPhone
        - (NSString *)name {
        WPhoneModel *wphoneModel = (WPhoneModel *)self.data;
        return wphoneModel.name;
        }
        - (NSString *)playMovie {
        WPhoneModel *wphoneModel = (WPhoneModel *)self.data;
        return wphoneModel.movieName;
        }
        - (NSString *)playMusic {
        WPhoneModel *wphoneModel = (WPhoneModel *)self.data;
        return wphoneModel.musicName;
        }
        @end
    • ViewController
      #import "ViewController.h"
      
      #import "CellPhone.h"
      
      #import "Ios.h"
      #import "IosModel.h" #import "Android.h"
      #import "AnroidModel.h" #import "WPhone.h"
      #import "WPhoneModel.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
      [super viewDidLoad];
      [self adapterWphone]; NSLog(@"%@",[self.delegate name]);
      NSLog(@"%@",[self.delegate playMovie]);
      NSLog(@"%@",[self.delegate playMusic]);
      } //适配iOS
      - (void)adapterIos {
      //数据源
      IosModel *iosModel = [[IosModel alloc]init];
      iosModel.name = @"iOS";
      iosModel.musicName = @"iOS--音乐";
      iosModel.movieName = @"iOS--电影"; //父类指针指向子类对象
      CellPhone *cellPhone = [[Ios alloc] initWithData:iosModel];
      self.delegate = cellPhone;
      } //适配andriod
      - (void)adapterAndriod {
      //数据源
      AnroidModel *anroidModel = [[AnroidModel alloc]init];
      anroidModel.name = @"Andriod";
      anroidModel.musicName = @"Andriod--音乐";
      anroidModel.movieName = @"Andriod--电影"; //父类指针指向子类对象
      CellPhone *cellPhone = [[Ios alloc] initWithData:anroidModel];
      self.delegate = cellPhone;
      } //适配Wphone
      - (void)adapterWphone {
      //数据源
      WPhoneModel *wphoneModel = [[WPhoneModel alloc]init];
      wphoneModel.name = @"WPhone";
      wphoneModel.musicName = @"WPhone--音乐";
      wphoneModel.movieName = @"WPhone--电影"; //父类指针指向子类对象
      CellPhone *cellPhone = [[Ios alloc] initWithData:wphoneModel];
      self.delegate = cellPhone;
      }
      - (void)setDelegate:(id<CellPhoneProtocol>)delegate {
      _delegate = delegate;
      }
      @end
    • 打印结果
      -- ::08.203781+ AdapterPattern[:] WPhone
      -- ::08.203983+ AdapterPattern[:] WPhone--电影
      -- ::08.204108+ AdapterPattern[:] WPhone--音乐

四,优缺点

  • 优点:
    解耦合,让视图类不合数据类产生耦合,使视图类更加独立。 新增加数据类的时候不需要修改视图类。
  • 缺点:
    会新增加很多类,使系统更凌乱,代码可读性更弱了。

五,demo  

AdapterPattern

iOS设计模式之适配器模式的更多相关文章

  1. iOS设计模式 - 适配器

    iOS设计模式 - 适配器 效果 说明 1. 为了让客户端尽可能的通用,我们使用适配器模式来隔离客户端与外部参数的联系,只让客户端与适配器通信. 2. 本教程实现了适配器模式的类适配器与对象适配器两种 ...

  2. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

  3. iOS 设计模式

    很赞的总结 iOS Design Patterns 中文版 IOS设计模式之一(MVC模式,单例模式) IOS设计模式之二(门面模式,装饰器模式) IOS设计模式之三(适配器模式,观察者模式) IOS ...

  4. iOS设计模式 - (1)概述

    近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了.花点时间学学设计模式. 之后将会写一系列博文, 记录设计模式学习过程. 当然, 由于我自己是搞iOS的, 所以之后设 ...

  5. 每天一个设计模式-3 适配器模式(Adapteer)

    每天一个设计模式-3 适配器模式(Adapteer) 1.现实中的情况 旧式电脑的硬盘是串口的,直接与硬盘连接,新硬盘是并口的,显然新硬盘不能直接连在电脑上,于是就有了转接线.好了,今天的学习主题出来 ...

  6. Head First 设计模式之适配器模式与外观模式

    Head First设计模式之适配器模式与外观模式 前言: 之前讲过装饰者模式,将对象包装起来并赋予新的职责,这一章我们也会将对象进行包装,只不过是让它们看起来不像自己而像是别的东西.这样就可以在设计 ...

  7. C#设计模式(7)——适配器模式(Adapter Pattern)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将“将现存的对象”在新的环境中进行调用 ...

  8. IOS设计模式之一(MVC模式,单例模式)

    iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...

  9. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

随机推荐

  1. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_01 File类_8_File类遍历(文件夹)目录功能

    遍历这个目录下的文件 遍历一个文件就会报错’ 不存在的路径,也会报空指针异常 遍历可以获取到隐藏的文件夹和文件.常见一个隐藏的文件和文件夹 ListFiles私有类型的数组

  2. 浅谈vue单页面seo问题

    最近做项目的时候,被要求做seo,由于项目已经开发完毕,且只需首页做seo,所以考虑再三,决定用prerender-spa-plugin结合vue-meta-info来实现首页的seo.如果你的页面是 ...

  3. oracle--本地网络配置tnsnames.ora和监听器listener.ora

    文件tnsnames.ora 是给orcl客户端使用 配置本地网络服务:(客户端) 第一种使用暴力方式直接操作: 修改:C:\app\Administrator\product\11.2.0\dbho ...

  4. 如何选择适合自己的Linux版本

    如何选择适合自己的Linux版本: 1.Linux桌面系统,首选Ubuntu; 2.服务器端的Linux系统,首选RHEL或CentOS,这两种中首选CentOS,如果公司有钱,不在乎成本也可以选择R ...

  5. 【洛谷p1981】表达式求值

    题前废话: 咱也不知道咱写了个什么神奇的代码导致_rqy都看不明白它是怎么re掉的, 代码的大致思路是这样的:对于这样一个中缀表达式,先转化成它的后缀表达式的形式,然后利用P1449 后缀表达式 这道 ...

  6. eclipse 使用技巧、经验 (编码、格式化模板、字体)

    版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/28697515 1.设置编码为U ...

  7. centos安装httprunner方法

    测试脚本执行的环境部署(在jenkins服务器中,要求jenkins服务器和目标的灰度环境是连通的): 一.安装python3.8 $python#看见2.6.6Python 2.6.6 (r266: ...

  8. SSH学习笔记(二)

    # 1. 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port 22 # SSH 预设使用 22 这个 port,您也可以使用多的 port ! # 亦即 ...

  9. maven_上传到私服,以及从私服下载

    公司由于没有maven,自己又想用,于是乎,就自己搭了一个nexus 1.苦逼不多说,将本地jar文件上传到maven 需要在本机(客户端windows)中的maven中的setting.xml添加这 ...

  10. cp 复制文件或目录

    1. 命令功能 cp --copy files and directories.复制文件或目录. 2. 语法格式 cp  [option]  source des cp  [option]  sour ...