桥接模式的原理解析
桥接模式也叫作桥梁模式,英文是Bridge Design Pattern。“Decouple an abstraction from its implementation so that the two can vary independently。”翻译成中文就是:”将抽象和实现解耦,让它们可以独立变化“。
API接口监控告警的例子:根据不同的告警规则,触发不同类型的警告。告警支持多种通知渠道,包括:邮件、短信、微信、自动语音电话。通知的紧急程度有多种类型,包括:SEVERE(严重)、URGENCY(紧急)、NORMAL(普通)、TRIVIAL(无关紧要)。不同的紧急程度对应不同的通知渠道。比如,SEVER(严重)级别的消息会通过”自动语音电话“告知相关人员。先来看最简单、最直接的一种实现方式。代码如下所示:
typedef enum : NSUInteger {
DMNotificationEmergencyLevelSevere,
DMNotificationEmergencyLevelUrgency,
DMNotificationEmergencyLevelNormal,
DMNotificationEmergencyLevelTrival,
} DMNotificationEmergencyLevel;
@interface DMNotification : NSObject
@property (nonatomic, strong) NSArray *emailAddresses;
@property (nonatomic, strong) NSArray *telephones;
@property (nonatomic, strong) NSArray *wechatIds;
- (void)notifyNotificationEmergencyLevel:(DMNotificationEmergencyLevel )level messageStr:(NSString *)messageStr;
@end
@implementation DMNotification
- (void)notifyNotificationEmergencyLevel:(DMNotificationEmergencyLevel )level messageStr:(NSString *)messageStr {
if (level == DMNotificationEmergencyLevelSevere) {
// ...自动语音电话
}else if (level == DMNotificationEmergencyLevelUrgency) {
// ...发微信
}else if (level == DMNotificationEmergencyLevelNormal) {
// ...发邮件
}else if (level == DMNotificationEmergencyLevelTrival) {
// ...发邮件
}
}
@end
DMNotification类的代码实现有一个最明显的问题,就是有很多if-else分支逻辑。实际上,如果每个分支中的代码都不复杂,后期也没有无限膨胀的可能(增加更多if-else)分支判断,那这样的设计问题并不大,没必要非得一定要摒弃if-else分支逻辑。
不过DMNotification类的代码显然不符合这个条件。因为每个if-else分支中的代码逻辑都比较复杂,发送通知的所有逻辑都扎堆在DMNotification类中。类的代码越多,就越难读懂,越难修改,维护的成本也就越高。很多设计模式都是视图将庞大的类拆分成更细小的类,然后再通过某种更合理的结构组装在一起。
针对DMNotification的代码,将不同渠道的发送逻辑剥离出来,形成独立的消息发送类(DMMsgSender相关类)。其中DMNotification类相当于抽象,DMMsgSender类相当于实现,两者可以独立开发,通过组合关系(也就是桥梁)任意组合在一起。所谓任意组合的意思就是,不同紧急程度的消息和发送渠道之间的对应关系,不是在代码中固定写死的,可以动态地去指定(比如,通过读取配置来获取对应关系)。代码重构之后,如下:
@protocol DMMsgSenderDelegate <NSObject>
- (void)send:(NSString *)msg;
@end
@interface DMTelephoneMsgSender : NSObject <DMMsgSenderDelegate>
- (instancetype)initWithTelephones:(NSArray *)telephones;
@end
@interface DMTelephoneMsgSender ()
@property (nonatomic, strong) NSArray *telephones;
@end
@implementation DMTelephoneMsgSender
- (instancetype)initWithTelephones:(NSArray *)telephones
{
if (self = [super init]) {
self.telephones = telephones;
}
return self;
}
- (void)send:(NSString *)msg
{
// 手机号发送信息
}
@end
@interface DMEmailMsgSender : NSObject <DMMsgSenderDelegate>
- (instancetype)initWithEmailAddresses:(NSArray *)emailAddresses;
@end
@interface DMEmailMsgSender ()
@property (nonatomic, strong) NSArray *emailAddresses;
@end
@implementation DMEmailMsgSender
- (instancetype)initWithEmailAddresses:(NSArray *)emailAddresses
{
if (self = [super init]) {
self.emailAddresses = emailAddresses;
}
return self;
}
- (void)send:(NSString *)msg
{
// 邮件发送信息
}
@end
@interface DMWechatMsgSender : NSObject <DMMsgSenderDelegate>
- (instancetype)initWithWechatIds:(NSArray *)wechatIds;
@end
@interface DMWechatMsgSender ()
@property (nonatomic, strong) NSArray *wechatIds;
@end
@implementation DMWechatMsgSender
- (instancetype)initWithWechatIds:(NSArray *)wechatIds
{
if (self = [super init]) {
self.wechatIds = wechatIds;
}
return self;
}
- (void)send:(NSString *)msg
{
// 微信发送信息
}
@end
@interface DMNotification : NSObject
- (instancetype)initWithMsgSender:(id<DMMsgSenderDelegate>)msgSender;
@property (nonatomic, strong, readonly) id<DMMsgSenderDelegate> msgSender;
@end
@interface DMNotification ()
@property (nonatomic, strong, readwrite) id<DMMsgSenderDelegate> msgSender;
@end
@implementation DMNotification
- (instancetype)initWithMsgSender:(id<DMMsgSenderDelegate>)msgSender
{
if (self = [super init]) {
self.msgSender = msgSender;
}
return self;
}
@end
@interface DMSevereNotification : DMNotification
- (void)notify:(NSString *)msg;
@end
@implementation DMSevereNotification
- (void)notify:(NSString *)msg
{
[self.msgSender send:msg];
}
@end
@interface DMUrgencyNotification : DMNotification
- (void)notify:(NSString *)msg;
@end
@implementation DMUrgencyNotification
- (void)notify:(NSString *)msg
{
[self.msgSender send:msg];
}
@end
@interface DMNormalNotification : DMNotification
- (void)notify:(NSString *)msg;
@end
@implementation DMNormalNotification
- (void)notify:(NSString *)msg
{
[self.msgSender send:msg];
}
@end
@interface DMTrivialNotification : DMNotification
- (void)notify:(NSString *)msg;
@end
@implementation DMTrivialNotification
- (void)notify:(NSString *)msg
{
[self.msgSender send:msg];
}
@end
使用的代码示例如下:
{
NSArray *telephones = [[NSArray alloc] init];
DMTelephoneMsgSender *telephoneMsgSender = [[DMTelephoneMsgSender alloc] initWithTelephones:telephones];
DMSevereNotification *severeNotification = [[DMSevereNotification alloc] initWithMsgSender:telephoneMsgSender];
NSArray *wechatIds = [[NSArray alloc] init];
DMWechatMsgSender *wechatMsgSender = [[DMWechatMsgSender alloc] initWithWechatIds:wechatIds];
DMUrgencyNotification *urgencyNotification = [[DMUrgencyNotification alloc] initWithMsgSender:wechatMsgSender];
NSArray *emailAddresses = [[NSArray alloc] init];
DMEmailMsgSender *emailMsgSender = [[DMEmailMsgSender alloc] initWithEmailAddresses:emailAddresses];
DMNormalNotification *normalNotification = [[DMNormalNotification alloc] initWithMsgSender:emailMsgSender];
DMTrivialNotification *trivialNotification = [[DMTrivialNotification alloc] initWithMsgSender:emailMsgSender];
// 严峻情况下
[severeNotification notify:@"严峻情况"];
// 紧急情况下
[urgencyNotification notify:@"紧急情况"];
// 一般情况
[normalNotification notify:@"一般情况"];
// 微不足道的情况
[trivialNotification notify:@"微不足道的情况"];
}
网友评论