一句话总结:
装饰模式是「套娃增强」,代理模式是「中介代购」,桥接模式是「两岸建桥」—— 三种模式形似而神不似,Android 系统里各显神通!
一、装饰模式(Decorator)—— 俄罗斯套娃
核心:动态扩展对象功能,层层包裹增强能力
Android 源码例子:Java IO 流在 Android 的应用
// 创建多层装饰的流
InputStream in = new FileInputStream("test.txt");
in = new BufferedInputStream(in); // 加缓冲
in = new GZIPInputStream(in); // 加解压
// 底层实现:装饰类继承同一接口
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in) {
super(in); // 持有被装饰对象的引用
}
@Override
public int read() throws IOException {
// 增强功能:缓冲读取
if (pos >= count) fillBuffer();
return buf[pos++] & 0xff;
}
}
使用场景:
- 需要动态/透明地扩展对象功能(如加密、压缩流)
- Android 中的
ContextWrapper包装Context(如Service包装ContextImpl)
特点:
- 装饰类和被装饰类实现相同接口
- 可以多层嵌套,灵活组合功能
二、代理模式(Proxy)—— 中介代购
核心:控制对象访问,替代原始对象处理额外逻辑
Android 源码例子:AIDL 生成的 Stub.Proxy
// frameworks/base/core/java/android/app/ActivityManagerNative.java
class ActivityManagerProxy implements IActivityManager {
private final IBinder mRemote;
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
public int startActivity(...) throws RemoteException {
// 代理核心:打包数据发送给 Binder 驱动
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
}
}
使用场景:
- 跨进程通信(如系统服务调用)
- 延迟加载(如 Glide 的图片占位代理)
- 权限控制(如检查权限后再执行实际逻辑)
特点:
- 代理类和被代理类实现相同接口
- 重点在于访问控制而非功能增强
三、桥接模式(Bridge)—— 跨江大桥
核心:分离抽象与实现,让两者独立变化
Android 源码例子:View 与 Drawable 的关系
// frameworks/base/core/java/android/view/View.java
public class View {
private Drawable mBackground; // 桥接的关键点
public void setBackground(Drawable background) {
mBackground = background;
mBackground.setBounds(...); // 委托给 Drawable 实现
}
}
// Drawable 的子类实现不同绘制逻辑
public class ColorDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
canvas.drawColor(mColor);
}
}
public class BitmapDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, ...);
}
}
使用场景:
- UI 框架设计(如
View与Drawable解耦) - 跨平台渲染(如
Surface与OpenGL/Vulkan桥接) - 数据库驱动设计(JDBC 的 Driver 与 Connection 分离)
特点:
- 抽象(如
View)持有实现(如Drawable)的引用 - 抽象和实现可以独立扩展(新增 View 类型不影响 Drawable 体系)
四、三种模式对比表
| 维度 | 装饰模式 | 代理模式 | 桥接模式 |
|---|---|---|---|
| 核心目的 | 动态增强对象功能 | 控制对象访问 | 解耦抽象与实现 |
| 关系特点 | 装饰类与被装饰类同接口 | 代理类与被代理类同接口 | 抽象层持有实现层引用 |
| 调用流向 | 单向包裹,逐层处理 | 单向转发(可能跨进程) | 双向独立扩展 |
| Android案例 | ContextWrapper → Context | ActivityManagerProxy | View + Drawable |
| 性能影响 | 可能增加调用链深度 | 跨进程代理有较大开销 | 几乎无额外开销 |
五、源码级原理剖析
1. 装饰模式在 Context 体系的应用
// ContextWrapper 装饰 ContextImpl
public class ContextWrapper extends Context {
Context mBase; // 被装饰对象
public ContextWrapper(Context base) {
mBase = base;
}
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent); // 委托给实际实现
}
}
// Activity 继承 ContextThemeWrapper(装饰链)
ContextImpl → ContextWrapper → ContextThemeWrapper → Activity
- 每层装饰添加新功能(如
ContextThemeWrapper增加主题支持)
2. 代理模式在 Binder 跨进程的底层实现
// frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
// 通过 ioctl 与内核通信
return IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
}
- 代理对象
BpBinder只负责打包数据,实际逻辑由远端BnBinder处理
3. 桥接模式在 Window 系统的运用
// Window 抽象与 WindowManagerImpl 实现分离
public abstract class Window {
public abstract void setContentView(View view);
}
public class PhoneWindow extends Window {
private DecorView mDecor; // 具体实现委托给 DecorView
}
// WindowManagerGlobal 管理实际窗口
public class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
}
Window负责抽象行为,WindowManagerGlobal处理具体实现(如与 WMS 交互)
六、使用场景口诀
「要增强功能用装饰,需控制访问找代理
抽象实现若多变,桥接模式来解耦
实际开发选择指南:
- 给
RecyclerView加滚动监听(装饰OnScrollListener) - 权限校验代理网络请求(代理模式拦截非法调用)
- 自定义 View 支持多种渲染引擎(桥接模式分离逻辑与渲染)
注意事项:
- 装饰模式不要嵌套超过 3 层(否则调试困难)
- 动态代理的性能问题(避免高频调用)
- 桥接模式适合框架设计,过度使用会增加类数量