• iOS设计模式之适配器模式


    一,适配器的定义

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

    二,适配器的结构图

      实现步骤:

    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
      • 打印结果
        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



  • 相关阅读:
    scp命令(基于ssh上传文件等)
    mac上安装ruby
    Access denied for user ''@'localhost' to database 'mysql'
    3.ruby语法基础,全部变量,实例变量,类变量,局部变量的使用和注意的要点
    2.ruby基本语法,类的定义
    1.ruby基本格式
    neo4j在linux下的安装
    mongodb导入json文件
    mongodb 安装启动
    Junit4
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/11482253.html
Copyright © 2020-2023  润新知