Android中的四种创建型模式:从简单工厂到构建者模式

131 阅读5分钟

一句话总结

四种模式就像不同段位的厨神开店:简单工厂是路边摊,老板凭菜名直接出餐;工厂方法是连锁店,每家分店自己决定招牌菜;抽象工厂是品牌中央厨房,统一供应全家桶套餐;而Builder则是DIY厨房,自由搭配食材分步烹饪。


一、简单工厂模式:快速创建的“一站式”服务

核心思想: 简单工厂模式由一个静态工厂类负责根据传入的参数,创建并返回不同类型的产品。它将对象的创建逻辑集中在一处,对客户端隐藏了具体的实例化细节。

Android源码实例: BitmapFactory 是该模式在 Android 中的经典应用。它提供了 decodeFile()decodeResource() 等一系列静态方法,根据输入来源(文件路径、资源ID等),封装了底层的图片解码和创建逻辑,直接返回一个 Bitmap 对象。

public static Bitmap decodeResource(Resources res, int id, Options opts) {
    // ...
    // 底层会根据传入的资源ID,调用不同的native方法来创建Bitmap对象
    // ...
}

优点与局限性: 简单工厂模式实现简单,客户端使用起来非常方便。然而,它的缺点也很明显:所有产品创建逻辑都集中在一个工厂类中,当需要增加新的产品类型时,必须修改工厂类,这违反了开闭原则。因此,它更适用于产品种类固定且不多的简单场景。


二、工厂方法模式:解耦与可扩展的“分店”模式

核心思想: 为了解决简单工厂的扩展性问题,工厂方法模式将创建对象的责任下放给子类。它定义一个抽象的工厂接口,但将具体的实例化过程延迟到实现它的子类中完成。

Android源码实例: Fragment 的生命周期方法 onCreateView() 完美诠释了这一模式。Fragment 基类定义了一个抽象的 onCreateView() 方法(虽然在源码中不是抽象的,但其意图是让子类必须实现),它是一个“工厂方法”,让每个具体的 Fragment 子类负责创建自己的视图,从而实现了视图创建逻辑与 Fragment 框架的分离。

// Fragment 基类中的“工厂方法”
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
        @Nullable Bundle savedInstanceState) {
    // ...
    // 子类负责返回具体的View实例,框架负责调用
    return null;
}

// 具体子类负责实现
class MyFragment extends Fragment {
    @Override
    public View onCreateView(...) {
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
}

优点: 工厂方法模式完全遵循了开闭原则。当需要增加一个新的产品时,只需创建一个新的具体工厂类来生产它,而无需修改原有的工厂代码。


三、抽象工厂模式:统一品牌的“全家桶”方案

核心思想: 抽象工厂模式是工厂方法模式的升级版,它不仅仅创建单个对象,而是为创建一系列相关或相互依赖的对象家族提供一个接口,而无需指定它们具体的类。

Android源码实例: Android的资源加载体系是抽象工厂的典型应用。Resources 类可以被视为一个抽象工厂,它提供了获取不同类型资源(DrawableStringColor等)的方法。而不同的设备配置(如语言、屏幕密度)和主题,对应着不同的具体工厂,这些工厂会返回一套相互兼容的资源对象。例如,在夜间模式下,系统会使用一套不同的抽象工厂实现,自动提供一套与夜间模式相符的 Drawable、Color等资源。

// Resources 抽象工厂提供了获取多种相关对象的方法
public abstract class Resources {
    public abstract Drawable getDrawable(int id);
    public abstract String getString(int id);
    public abstract ColorStateList getColorStateList(int id);
    // ...
}

优点与局限性: 抽象工厂确保了同一“产品家族”下的所有对象都是兼容的,这在构建复杂的、主题化的系统时非常有用。但其缺点是,随着产品族的增加,其接口和类的数量会急剧膨胀,导致系统复杂度很高。


四、Builder 模式:复杂对象的“逐步定制”

核心思想: Builder(构建者)模式与工厂模式不同,它不关注创建哪个类的对象,而是关注如何分步构建一个复杂对象。它将对象的构建过程与其内部表示分离,使得客户端可以用同样的过程创建出不同的表示。

Android源码实例: AlertDialog.BuilderBuilder 模式最知名的例子。由于一个对话框可能包含标题、消息、按钮、列表等众多可选元素,如果使用传统的构造函数,会面临参数过多的问题。Builder 模式提供了一系列链式调用的 setter 方法来设置这些参数,最后通过 create()show() 方法来创建并返回最终的 AlertDialog 对象。

new AlertDialog.Builder(context)
    .setTitle("警告")
    .setMessage("确定删除?")
    .setPositiveButton("确定", null)
    .create() // create方法封装了最终的构建逻辑
    .show();

优点与区别: Builder 模式的优点在于它使得创建过程清晰、可读性高,且可以灵活地省略或调整参数的顺序,完美解决了“构造器参数爆炸”的问题。与工厂模式相比,Builder 模式不强制通过继承来扩展产品,而是通过不同的构建步骤来产生不同的结果。