桥接模式定义:
将抽象部分与它的实现部分分离,使它们都可以独立的变化。
原理:抽象层与实现层相分离,抽象层定义了供客户端调用的抽象接口,实现层提供了具体的逻辑,实现类的引用被封装到抽象层的实例中,桥接就此形成。
原始代码示例:
首先创建两个类:XiaoMiRemote(小米遥控器) XiaoMiTV(小米电视)
XiaoMiTV.h
#import <Foundation/Foundation.h>
@interface XiaoMiTV : NSObject
// 电视提供给外界的接口
- (void)loadCommand:(NSString *)command;
@end
XiaoMiTV.m
#import "XiaoMiTV.h"
@implementation XiaoMiTV
- (void)loadCommand:(NSString *)command {
// 点击之后, 实现的业务逻辑
NSLog(@"您按的是:----%@",command);
}
@end
XiaoMiRemote.h
#import <Foundation/Foundation.h>
#import "XiaoMiTV.h"
@interface XiaoMiRemote : NSObject
@property (nonatomic, strong) XiaoMiTV *TV;
// 方向控制
- (void)up;
- (void)down;
- (void)left;
- (void)right;
@end
XiaoMiRemote.m
#import "XiaoMiRemote.h"
@implementation XiaoMiRemote
- (void)up {
[self.TV loadCommand:@"up"];
}
- (void)down {
[self.TV loadCommand:@"down"];
}
- (void)left {
[self.TV loadCommand:@"left"];
}
- (void)right {
[self.TV loadCommand:@"right"];
}
@end
按照上面的操作,再次创建KJRemote,KJTV
KJRemote.h
#import <Foundation/Foundation.h>
#import "KJTV.h"
@interface KJRemote : NSObject
@property (nonatomic, strong) KJTV *TV;
// 方向控制
- (void)up;
- (void)down;
- (void)left;
- (void)right;
- (void)action1;
- (void)action2;
@end
KJRemote.m
#import "KJRemote.h"
@implementation KJRemote
- (void)up {
[self.TV loadCommandKJ:@"up"];
}
- (void)down {
[self.TV loadCommandKJ:@"down"];
}
- (void)left {
[self.TV loadCommandKJ:@"left"];
}
- (void)right {
[self.TV loadCommandKJ:@"right"];
}
- (void)action1 {
[self.TV loadCommandKJ:@"action1"];
}
- (void)action2 {
[self.TV loadCommandKJ:@"action2"];
};
@end
KJTV.h
#import <Foundation/Foundation.h>
@interface KJTV : NSObject
// 电视提供给外界的接口
- (void)loadCommandKJ:(NSString *)command;
@end
KJTV.m
#import "KJTV.h"
@implementation KJTV
- (void)loadCommandKJ:(NSString *)command {
// 点击之后, 实现的业务逻辑
NSLog(@"您按的是KJ:----%@",command);
}
@end
ViewController.m
#import "ViewController.h"
#import "XiaoMiTV.h"
#import "XiaoMiRemote.h"
#import "KJTV.h"
#import "KJRemote.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
XiaoMiTV *TV = [[XiaoMiTV alloc] init];
XiaoMiRemote *remote = [[XiaoMiRemote alloc] init];
remote.TV = TV;
[remote up];
KJTV *TV2 = [[KJTV alloc] init];
KJRemote *remote2 = [[KJRemote alloc] init];
remote2.TV = TV2;
[remote2 action1];
[remote2 up];
}
@end
可是我们可以把康佳的电视,交给小米的遥控器去控制嘛?
答案肯定是不可以,我们使用桥接模式,把它们共同的点去抽取出来。
桥接抽取
思路: 把遥控器抽象出一个父类, 把电视机也抽象出一个父类
用抽象的遥控器对抽象电视机类进行引用,具体的实现由他们的子类来做
首先创建两个抽象的父类,Remote,TV
TV.h
#import <Foundation/Foundation.h>
@interface TV : NSObject
// 电视机提供给外界调用的一个方法
- (void)loadCommand:(NSString *)command;
@end
TV.m
#import "TV.h"
@implementation TV
- (void)loadCommand:(NSString *)command {}
@end
Remote.h
#import <Foundation/Foundation.h>
#import "TV.h"
@interface Remote : NSObject
@property (nonatomic, strong) TV *tv;
- (void)setCommand:(NSString *)commmand;
@end
Remote.m
#import "Remote.h"
@implementation Remote
- (void)setCommand:(NSString *)commmand {
[self.tv loadCommand:commmand];
}
@end
创建继承自Remote的子类SubRemote
SubRemote.h
#import "Remote.h"
//这种不改变父类的方法,由子类去拓展方法的实现,符合开闭原则
@interface SubRemote : Remote
// 方向控制
- (void)up;
- (void)down;
- (void)left;
- (void)right;
@end
SubRemote.m
#import "SubRemote.h"
@implementation SubRemote
// 方向控制
- (void)up {
[super setCommand:@"up"];
}
- (void)down {
[super setCommand:@"down"];
}
- (void)left {
[super setCommand:@"left"];
}
- (void)right {
[super setCommand:@"right"];
}
@end
创建继承自TV的TVXiaoMI和TVKJ
TVXiaoMI.m
#import "TVXiaoMI.h"
@implementation TVXiaoMI
- (void)loadCommand:(NSString *)command {
if ([command isEqualToString:@"up"]) {
NSLog(@"您按的是XM:----%@",command);
}
else if ([command isEqualToString:@"down"]){
NSLog(@"您按的是XM:----%@",command);
}
else if ([command isEqualToString:@"left"]){
NSLog(@"您按的是XM:----%@",command);
}
else if ([command isEqualToString:@"right"]){
NSLog(@"您按的是XM:----%@",command);
}
else {
NSLog(@"超出范围");
}
}
@end
TVKJ.m
#import "TVKJ.h"
@implementation TVKJ
- (void)loadCommand:(NSString *)command {
if ([command isEqualToString:@"up"]) {
NSLog(@"您按的是KJ:----%@",command);
}
else if ([command isEqualToString:@"down"]){
NSLog(@"您按的是KJ:----%@",command);
}
else if ([command isEqualToString:@"left"]){
NSLog(@"您按的是KJ:----%@",command);
}
else if ([command isEqualToString:@"right"]){
NSLog(@"您按的是KJ:----%@",command);
}
else {
NSLog(@"超出范围");
}
}
@end
ViewController.m
#import "ViewController.h"
#import "XiaoMiTV.h"
#import "XiaoMiRemote.h"
#import "KJTV.h"
#import "KJRemote.h"
#import "SubRemote.h"
#import "TVKJ.h"
#import "TVXiaoMI.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 遥控器调用康佳电视
SubRemote *subremote = [[SubRemote alloc] init];
subremote.tv = [[TVKJ alloc] init];
[subremote up];
// 遥控器来调用小米
subremote.tv = [[TVXiaoMI alloc] init];
[subremote up];
[subremote down];
}
@end
桥接模式的特点:
1. 将依赖具体的实现,改为依赖抽象. 得到松耦合的状态
2. 分离了接口和实现部分
3. 提高了扩展性.