iOS设计模式之美-工厂模式
iOS设计模式之美-抽象工厂模式
iOS设计模式之美-生成器模式
iOS设计模式之美-适配器模式
1.何为适配器模式
将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作
适配器模式你可能不了解,但电源适配器你总有点熟悉吧?对,就是那个iPhone
手机充电器那个方形的头,上面有一段描述为 输入:100-240V 。这什么意思呢?其实每个国家电源电压都是有差异的,中国为220V,日本100V,其它一些欧洲国家为110V。如果没有电源适配器,我们的手机将无法正常充电。我们是重新购买合适的充电器呢?还是要求每个国家都提供各种不同电压的电源呢?明显上述两种方法都不合适与不合理。于是适配器便应运而生了,为我们在不同环境下不同电压提供了一个中转的作用,将其转换成合适我们当前充电器适合的电压。
2.何时使用适配器模式
- 已有类的接口与需求不匹配(电源电压不合适)
- 想要一个可复用的类,该类能够同可能带有不兼容接口的其他类协作(想要个能在各种不同电压环境下充电的万能充电器)
- 需要适配一个类的几个不同的子类,可是让每个子类去子类化一个类适配器又不现实(针对不同电压环境下生产不同类型的充电器十分麻烦并且不现实)
3.适配器模式静态类结构图
适配器模式又分为 类适配器 和 对象适配器
- Client:使用者(iPhone)
- <Target>:目标需求接口(iPhone统一需要的电压要求)
- Adapter:适配器(电源适配器)
- Adaptee:被适配者(不同环境下的电压)
3.1类适配器
类适配器.png类适配器中适配器与被适配者是继承关系
3.2对象适配器
对象适配器.png对象适配器中适配器与被适配者是组合关系
4.类配器与对象适配器的区别
类适配 | 对象适配器 |
---|---|
只针对单一具体的Adaptee类,把Adaptee适配到<Target> | 可以适配多个Adaptee及其子类 |
易于重载Adaptee的行为,因为是通过直接的子类化进行适配 | 难以重载Adaptee的行为,需要借助于子类的对象而不是Adaptee本身 |
只有一个Adaptee对象,无需额外的的指针间接访问Adaptee | 需要额外的指针以间接访问Adaptee并适配其行为 |
5.案例
上述电源适配器为对象适配器,所以下面代码将以如何实现对象适配器为例
WCQRecharge.h
//定义标准输出电压协议接口
#import <Foundation/Foundation.h>
@protocol WCQRecharge <NSObject>
- (void)recharge;
@end
WCQRechargeAdapter.h
//定义可转换任意电压且提供标准电压输出协议的电源适配器
#import <Foundation/Foundation.h>
#import "WCQRecharge.h"
@interface WCQRechargeAdapter : NSObject<WCQRecharge>
- (instancetype)initWithTension:(id)tension;
@end
WCQRechargeAdapter.m
#import "WCQRechargeAdapter.h"
#import "WCQ110VTension.h"
#import "WCQ220VTension.h"
@interface WCQRechargeAdapter ()
@property (nonatomic, strong) id tension;
@end
@implementation WCQRechargeAdapter
- (instancetype)initWithTension:(id)tension {
if (self = [super init]) {
_tension = tension;
}
return self;
}
- (void)recharge {
if ([_tension isMemberOfClass:[WCQ220VTension class]]) {
[_tension tensionOf220V];
}else if ([_tension isMemberOfClass:[WCQ110VTension class]]) {
[_tension tensionOf110V];
}
}
@end
WCQ220VTension.h
//定义需要转换的电压
#import <Foundation/Foundation.h>
@interface WCQ220VTension : NSObject
- (void)tensionOf220V;
@end
WCQ220VTension.m
#import "WCQ220VTension.h"
@implementation WCQ220VTension
- (void)tensionOf220V {
NSLog(@"220V");
}
@end
110V电压同理这里不贴了......
客户端(iPhone)调用代码示例:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
id tension = [[WCQ110VTension alloc] init];
WCQRechargeAdapter *rechargeAdapter = [[WCQRechargeAdapter alloc] initWithTension:tension];
[rechargeAdapter recharge];
}
这里我们能够看到在使用同一个电源适配器的情况下,即使将tension
换成WCQ220VTension
进行初始化,同样能满足用户的充电需求。同时适配器模式在对原有系统或第三方类库接口变更上也能做到很好的兼容,我们只需在所使用的适配器类中进行相应的调整即可。
以上为本人个人理解与分享,如有错误欢迎指出😊
recharge.png
网友评论