美文网首页
[设计模式]05.适配器模式

[设计模式]05.适配器模式

作者: 沈枫_ShenF | 来源:发表于2019-11-09 12:10 被阅读0次

    适配器模式有两种:

    1.类适配器
    2.对象适配器

    一、类适配器

    适配器Adapter通过继承被适配对象Adaptee来适配两个接口。

    类适配器UML图

    实例讲解

    最常用的例子:美元转人民币

    1.目标接口

    @protocol TargetCNYProtocol <NSObject>
    // 转化后的人民币
    - (float)getCNY;
    @end
    

    2.适配对象

    @interface AdapteeUSD : NSObject
    
    - (float)getUSD;
    
    @implementation AdapteeUSD
    - (float)getUSD {
        return 100;
    }
    @end
    

    3.适配器继承适配对象

    @interface AdapterCNY : AdapteeUSD <TargetCNYProtocol>
    
    @end
    
    @implementation AdapterCNY
    - (float)getCNY {
        return [self getUSD] * 6.61f;
    }
    @end
    

    4.调用

     AdapterCNY *adapterCNY = [[AdapterCNY alloc] init];
     float cny = [adapterCNY getCNY];
     NSLog(@"cny: %.2f", cny);
    

    二、对象适配器

    适配器Adapter不继承被适配对象Adaptee, 他们是一个关联关系,
    相当于引用了这个类。

    对象适配器UML图

    我们在开发项目时经常会遇到这种情况,视图里持有一个model,让model给视图里的控件赋值,比如:

    @interface ColorView : UIView
    
    @property (nonatomic, strong)Model *model;
    
    @end
    
    @interface Model : NSObject
    @property (nonatomic, strong) UIColor *smallViewColor; /**< 颜色 */
    @property (nonatomic, copy) NSString *userName; /**< 用户名 */
    @property (nonatomic, copy) NSString *password; /**< 密码 */
    @end
    

    但是当外部传来新的不一样的NewModel时就无法再套用:

    @interface NewModel : NSObject
    @property (nonatomic, strong) NSString *smallViewColor; /**< 颜色 */
    @property (nonatomic, copy) NSString *userName; /**< 用户名 */
    @property (nonatomic, copy) NSString *password; /**< 密码 */
    @end
    

    可以看出视图跟model需要解耦。我们需要定义一个统一的接口,这个接口根据视图要显示的内容规定出统一口径,那外部传给视图的model可能不同,就需要根据这个统一口径来进行适配。

    根据视图上的内容,这个接口是:

    // 目标接口
    @protocol TargeyProtocol <NSObject>
    
    - (UIColor *)smallViewColor; /**< 颜色 */
    
    - (NSString *)UserName; /**< 用户名 */
    
    - (NSString *)password; /**< 密码 */
    
    @end
    

    抽象适配器:

    #import <UIKit/UIKit.h>
    #import "TargeyProtocol.h"
    
    @interface ColorViewAdapter : NSObject <TargeyProtocol>
    
    @property (nonatomic, strong) id model; /**< 输入的模型数据 */
    
    - (instancetype)initWithModel:(id)model; /**< 初始化的一个方法 */
    
    @end
    
    @implementation ColorViewAdapter
    
    - (instancetype)initWithModel:(id)model {
        self = [super init];
        if (self) {
            self.model = model;
        }
        return self;
    }
    
    - (UIColor *)smallViewColor {
        return nil;
    }
    
    - (NSString *)UserName {
        return nil;
    }
    
    - (NSString *)password {
        return nil;
    }
    
    @end
    

    NewModelAdapter:

    #import "ColorViewAdapter.h"
    
    @interface NewModelAdapter : ColorViewAdapter
    
    @end
    
    @implementation NewModelAdapter
    
    - (UIColor *)smallViewColor {
        NewModel *model = self.model;
        
        if ([model.smallViewColor isEqualToString:@"blue"]) {
            return [UIColor  blueColor];
        } else {
            return [UIColor redColor];
        }
    }
    
    - (NSString *)UserName {
        NewModel *model = self.model;
        return model.userName;
    }
    
    - (NSString *)password {
        NewModel *model = self.model;
        return model.password;
    }
    
    
    @end
    
    

    而视图中只需有个遵循接口的model即可:

    #import "TargeyProtocol.h"
    
    @interface ColorView : UIView
    
    - (void)loadModel:(id <TargeyProtocol>)model;
    
    @end
    
    

    实现:

    #import "ColorView.h"
    
    @interface ColorView ()
    @property (nonatomic, strong) UIView   *smallView;
    @property (nonatomic, strong) UILabel  *userLabel;
    @property (nonatomic, strong) UILabel  *pswLabel;
    @end
    
    @implementation ColorView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        
        self = [super initWithFrame:frame];
        if (self) {
            [self setupUI];
            
        }
        return self;
    }
    
    // 添加UI
    - (void)setupUI {
        // 灰色的view
        self.backgroundColor = [UIColor lightGrayColor];
        CGFloat width = self.bounds.size.width;
        self.smallView = [[UIView alloc] initWithFrame:CGRectMake(0, 60, width,200)];
        [self addSubview:self.smallView];
        
        // 用户名
        self.userLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 100, 150, 25)];
        [self addSubview:self.userLabel];
        
        // 密码
        self.pswLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 130, 150, 25)];
        [self addSubview:self.pswLabel];
    }
    
    // 给属性赋值
    - (void)loadModel:(id <TargeyProtocol>)model {
        self.pswLabel.text = model.password;
        self.userLabel.text = model.UserName;
        self.smallView.backgroundColor = model.smallViewColor;
        
    }
    
    @end
    

    调用:

    - (void)viewDidLoad {
        [super viewDidLoad];
        ColorView *colorView = [[ColorView alloc] initWithFrame:self.view.bounds];
        
        // 赋值模型
        NewModel *model = [[NewModel alloc] init];
        model.smallViewColor = @"blue";
        model.userName = @"张三";
        model.password = @"1-1-1-1";
        
        NewModelAdapter *newModelAdapter = [[NewModelAdapter alloc] initWithModel:model];
        [colorView loadModel:newModelAdapter];
    
        // 添加
        [self.view addSubview:colorView];
    }
    

    可以看出,view跟model通过适配器解耦了,无论外部传的是哪个model,只要它遵循接口就可以了。

    相关文章

      网友评论

          本文标题:[设计模式]05.适配器模式

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