Android中的设计模式:构建健壮且可维护的应用

254 阅读6分钟

一句话总结

Android 里的设计模式就像手机内部的小工厂,每个车间(类)分工明确,流水线(模式)高效运转,最终组装出丝滑的 App!


一、创建型模式:对象的构建与封装

创建型模式的核心在于如何优雅地创建对象,它封装了复杂的创建逻辑,提供更灵活的实例化方式。

1. 单例模式(Singleton):全局共享的唯一实例

原理与应用:单例模式确保一个类在整个应用生命周期中只有一个实例,并提供一个全局访问点。这对于管理那些需要全局共享且消耗资源的资源(如数据库连接、配置管理器)至关重要。

在 Android 中,系统服务是单例模式的典型应用。例如,AccessibilityManager 通过 Context.getSystemService() 获取,其底层源码通过静态方法和双重检查锁定来确保只有一个实例被创建。

// frameworks/base/core/java/android/view/accessibility/AccessibilityManager.java
public static AccessibilityManager getInstance(Context context) {
    synchronized (sInstanceSync) {
        if (sInstance == null) {
            sInstance = new AccessibilityManager(context);
        }
        return sInstance;
    }
}

优点与风险:单例模式能有效节约内存,但其生命周期与应用绑定,若持有 Activity Context,极易引发内存泄漏。因此,使用时务必传入 Application Context

2. 建造者模式(Builder):复杂对象的逐步构建

原理与应用:建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这对于构造拥有众多可选参数的对象特别有用,避免了“构造器爆炸”的问题。

Android 中的 AlertDialogNotification 是该模式的完美示例。开发者不需要关心如何实例化一个复杂的对话框,只需通过链式调用 AlertDialog.Builder 的方法,一步步配置标题、消息、按钮等,最后调用 create()show() 来得到最终对象。

// Android SDK 中 AlertDialog.Builder 的使用
AlertDialog.Builder builder = new AlertDialog.Builder(context)
    .setTitle("Title")
    .setMessage("Message")
    .setPositiveButton("OK", null)
    .setNegativeButton("Cancel", null);
builder.show();

优点:建造者模式提升了代码的可读性和可维护性,使得创建复杂对象的过程清晰且不易出错。

3. 工厂模式(Factory):隐藏创建的细节

原理与应用:工厂模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。它将对象的实例化过程封装在工厂类中,对使用者隐藏了具体的创建逻辑。

BitmapFactory 是 Android 中典型的工厂模式。它提供了 decodeFile()decodeResource() 等一系列静态工厂方法,根据不同的输入来源(文件、资源、字节流等)创建 Bitmap 对象。开发者无需了解 Bitmap 是如何在底层通过 JNI 调用 native 方法创建的,只需要调用相应的工厂方法即可。

// frameworks/base/graphics/java/android/graphics/BitmapFactory.java
public static Bitmap decodeFile(String pathName, Options opts) {
    // ... 内部封装了复杂的流处理和 JNI 调用
    Bitmap bm = nativeDecodeFileDescriptor(path, ...);
    return bm;
}

优点:工厂模式使得代码更具扩展性。例如,如果未来需要支持新的图片格式,只需在工厂内部添加相应的处理逻辑,而不需要改变调用方的代码。


二、行为型模式:对象间的通信与协作

行为型模式关注对象之间的职责划分和算法分配,使得系统中的各个对象能够高效地协作。

1. 观察者模式(Observer):解耦的数据通信

原理与应用:观察者模式定义了一种一对多的依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新。

在 Android 中,LiveData 是观察者模式的绝佳体现。LiveData 作为被观察者,持有数据;ActivityFragment 作为观察者,通过 observe() 方法订阅 LiveData。当数据发生变化时,LiveData 会自动通知所有活跃的观察者,实现数据与 UI 的自动同步。

优点与风险:该模式实现了数据源与 UI 的彻底解耦,但如果观察者没有正确地移除订阅,可能会导致内存泄漏。LiveData 结合 LifecycleOwner 自动管理生命周期,有效解决了这一问题。

2. 责任链模式(Chain of Responsibility):事件的层层传递

原理与应用:责任链模式允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。请求沿着这条链传递,直到有一个对象处理它。

Android 的事件分发机制严格遵循这一模式。触摸事件从最顶层的 Activity 沿着 ViewGroup 树向下传递,每个 ViewGroup 节点都有机会通过 onInterceptTouchEvent() 拦截事件。如果事件没有被拦截,它将继续向下传递给子 View。如果子 View 最终没有处理该事件,事件将反向传递回父 ViewGroup,由其 onTouchEvent() 方法来处理。

优点:该模式使得事件处理逻辑更加灵活,可以动态地调整事件流向,而无需修改各个节点的代码。

3. 策略模式(Strategy):算法的动态切换

原理与应用:策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。这使得算法可以在运行时根据需要自由切换。

Android 的动画系统中的 Interpolator(插值器)接口是策略模式的典型应用。ObjectAnimator 在执行动画时,可以接受一个 Interpolator 接口作为参数。开发者可以传入不同的具体实现类(如 LinearInterpolatorAccelerateDecelerateInterpolatorBounceInterpolator)来改变动画的速度变化曲线,而动画的底层实现代码无需做任何修改。

优点:策略模式将算法的实现与使用它的客户端彻底分离,使得算法的扩展和替换变得非常简单。


三、结构型模式:类的组合与封装

结构型模式关注如何将类和对象组织成更大的结构。

适配器模式(Adapter):接口的兼容性转换

原理与应用:适配器模式将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而无法协同工作的类可以一起工作。

在 Android 中,RecyclerView.Adapter 是该模式的完美体现。它作为数据源(如 List<T>)和 RecyclerView 之间的“转接头”,将抽象的数据转换为 RecyclerView 能够理解和渲染的 View 格式。

public abstract static class Adapter<VH extends ViewHolder> {
    public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
    public abstract void onBindViewHolder(VH holder, int position);
    // ...
}

优点:适配器模式实现了数据与 UI 的解耦,使得同一个 RecyclerView 视图组件可以展示不同类型的数据,极大地增强了代码的灵活性和可重用性。