美文网首页
iOS设计模式之桥接模式

iOS设计模式之桥接模式

作者: 点滴86 | 来源:发表于2024-05-18 23:09 被阅读0次

    桥接模式的原理解析

    桥接模式也叫作桥梁模式,英文是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:@"微不足道的情况"];
    }
    

    相关文章

      网友评论

          本文标题:iOS设计模式之桥接模式

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