iOS设计模式之适配器模式

一,适配器的定义

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

二,适配器的结构图

  实现步骤:

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

结构图:
iOS设计模式之适配器模式

 

 

 

 

 

 

 

 

 

 


三,代码示例

  • 接口协议
    • 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
    • 打印结果
      2019-09-07 17:32:08.203781+0800 AdapterPattern[12274:6524407] WPhone
      2019-09-07 17:32:08.203983+0800 AdapterPattern[12274:6524407] WPhone--电影
      2019-09-07 17:32:08.204108+0800 AdapterPattern[12274:6524407] WPhone--音乐

四,优缺点

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

五,demo  

AdapterPattern



iOS设计模式之适配器模式

上一篇:Effetive C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝


下一篇:多线程06-多线程共享数据的方式(经验小结)