iOS_设计模式学习:桥接模式

本文介绍桥接模式的概念、适用场景及实现方式。通过一个具体的例子,详细解释了如何通过对象组合来实现继承无法达成的效果,使得抽象部分与其实现部分可以独立变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习《Objective-C编程之道:iOS设计模式解析》,本文是对桥接模式的一个分析和例子实现。

例子地址:Bryanthelol/iOS_DesignPattern

里面包含书的例子和我自己实现的例子。

标签:接口适配


一、桥接模式是什么

桥接模式的目的是把抽象层次结构从其实现中分离出来,使其能够独立变更。

抽象层定义了供客户端使用的上层的抽象接口

实现层次结构定义了供抽象层次使用的底层接口

实现类的引用被封装于抽象层的实例中时

桥接就形成了

这样的解释肯定还是让人看不懂。用白话来说就是:

  • 存在两个Base类,这两个类分别代表:抽象的Base类和实现的Base类
    • Abstraction Base Class
    • Implementation Base Class
  • 抽象Base类有很多不同的子类
  • 实现Base类同样有很多不同的子类
  • 抽象Base类持有实现Base类的一个实例
  • 然后这个抽象Base类调用自身的方法,这个方法会调用其持有的实现Base类的实例方法(在使用时,实现Base类的实例被赋值了一个初始化了的实现子类)

这样,想添加新的实现子类,只需要创建一个继承自实现Base类的子类,重写其实现Base类的方法(这个方法就是上面抽象Base类会调用到的方法)。

这对抽象Base类不会有任何影响,并且如果想修改抽象Base类,或者创建更多的抽象子类,也不会影响实现Base类及其子类。

文字看起来还是挺绕,直接上图:

二、桥接模式适用范围:

  • 不想在抽象类与其实现类之间形成固定的绑定关系,可以再运行的时候切换
  • 抽象类和实现类都可以通过子类继承达到扩展
  • 抽象类不能影响调用者的代码
  • 抽象类有很多类型的子类或者实现类同样也有很多类型的子类

三、用代码讲解例子

步骤一:

首先,我们有一个抽象类CarBaseClass,代表车这个类型:

CarBaseClass.h
CarBaseClass.m
复制代码

还有一个实现类DrivingCarBaseClass, 代表开车这样一种操作:

DrivingCarBaseClass.h
DrivingCarBaseClass.m
复制代码
步骤二:

然后到了桥接模式的关键一步:

  • 让CarBaseClass抽象类持有DrivingCarBaseClass实现类的实例,这便完成了两个BaseClass最关键的桥接行为
CarBaseClass.h

@class DrivingCarBaseClass;

@interface CarBaseClass : NSObject {
    @private
    DrivingCarBaseClass *_drivingCar;
}

@property(nonatomic, strong) DrivingCarBaseClass *drivingCar;


复制代码
步骤三:

然后根据具体的情况,定义需要桥接的方法。在这里,实现类DrivingCarBaseClass有一个开车的动作,参数为坐车的人数:

DrivingCarBaseClass.h

@interface DrivingCarBaseClass : NSObject

- (void)drive:(NSUInteger)NumOfPerson;

@end

复制代码

这里需要注意的点——实现的Base类只需定义接口,具体的实现则交给继承的子类,比如DrivingSportsCarClass(驾驶跑车类,从DrivingCarBaseClass继承):

DrivingSportsCarClass.m

@implementation DrivingSportsCarClass

// 重载
- (void)drive:(NSUInteger)NumOfPerson {
    // do something...
}

@end

复制代码
步骤四:

这时我们回到抽象类CarBaseClass,现在需要把调用实现类drive方法的桥接行为包装起来。

CarBaseClass.h

@class DrivingCarBaseClass;

@interface CarBaseClass : NSObject {
    @private
    DrivingCarBaseClass *_drivingCar;
}

@property(nonatomic, strong) DrivingCarBaseClass *drivingCar;

// 新添加的
- (void)setNumOfPersonInCar:(NSUInteger)num;

复制代码
CarBaseClass.m

#import "CarBaseClass.h"
#import "DrivingCarBaseClass.h"

@implementation CarBaseClass

@synthesize drivingCar = _drivingCar;

- (void)setNumOfPersonInCar:(NSUInteger)num {
    [_drivingCar drive:num];
}

@end

复制代码

步骤四完成的是概念图里的这里:

步骤五:

根据具体需要,创建抽象类CarBaseClass的子类,比如跑车类SportsCarClass。

抽象类负责定义方法的接口,跑车类这个子类则负责实现方法。

比如,我们有一个“与女孩兜风”的方法goForDriveWithGirl。

现在抽象类CarBaseClass里定义:

CarBaseClass.h

@class DrivingCarBaseClass;

@interface CarBaseClass : NSObject {
    @private
    DrivingCarBaseClass *_drivingCar;
}

@property(nonatomic, strong) DrivingCarBaseClass *drivingCar;

- (void)setNumOfPersonInCar:(NSUInteger)num;

// 新添加的
- (void)goForDriveWithGirl;

复制代码

然后在抽象子类SportsCarClass里实现:

SportsCarClass.m

@implementation SportsCarClass

- (void)goForDriveWithGirl {
    [super setNumOfPersonInCar:2];
}

@end

复制代码

这里的关键则是调用的父类的桥接方法,从而达到抽象子类和实现子类之间的沟通。

四、总结

首先,桥接模式的好处是通过对象组合实现继承达不到的事情。

引用《Objective-C编程之道:iOS设计模式解析》一书的话(略作修改):

通过桥接模式,可以看到对象组合的力量。我们为实现Base类搭建的桥接不可能通过直接继承达到。这也是优先使用对象组合而不是继承的一个原因。

其次,桥接模式是把一个接口适配到不同接口的一种方式。

如果我们苦于“如何从实现中把抽象分离出来而又要让它们联系在一起”的时候,就用桥接模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值