安卓常见的设计模式

一、Android 中常见的设计模式

1. 单例模式 Singleton

作用

保证一个类只有一个实例,并提供全局访问点。

Android 中常见场景

  • Application
  • SharedPreferences
  • RoomDatabase
  • Retrofit
  • OkHttpClient
  • 图片加载库实例
  • 全局配置管理类

示例

public class AppManager {

    private static volatile AppManager instance;

    private AppManager() {}

    public static AppManager getInstance() {
        if (instance == null) {
            synchronized (AppManager.class) {
                if (instance == null) {
                    instance = new AppManager();
                }
            }
        }
        return instance;
    }
}

面试常问

问:单例模式有哪几种写法?

常见写法:

  1. 饿汉式
  2. 懒汉式
  3. 双重检查锁 DCL
  4. 静态内部类
  5. 枚举单例

问:DCL 为什么要加 volatile

因为创建对象不是原子操作,大致分为:

1. 分配内存
2. 初始化对象
3. 将引用指向内存

如果发生指令重排序,可能变成:

1. 分配内存
2. 引用指向内存
3. 初始化对象

其他线程可能拿到一个还没初始化完成的对象。

volatile 可以禁止指令重排序,保证可见性。


2. Builder 建造者模式

作用

用于创建复杂对象,避免构造方法参数过多。

Android 中常见场景

  • AlertDialog.Builder
  • Notification.Builder
  • OkHttpClient.Builder
  • Retrofit.Builder
  • Glide.with().load().into()

示例

AlertDialog dialog = new AlertDialog.Builder(context)
        .setTitle("提示")
        .setMessage("确定删除吗?")
        .setPositiveButton("确定", null)
        .setNegativeButton("取消", null)
        .create();

优点

  • 代码可读性好
  • 参数灵活
  • 适合创建复杂对象

面试常问

问:Builder 模式和构造方法相比有什么优势?

答:

如果对象参数很多,构造方法会变得很长:

new User("Tom", 18, "男", "北京", "123456");

可读性差,也容易传错参数。

Builder 写法更清晰:

User user = new User.Builder()
        .name("Tom")
        .age(18)
        .gender("男")
        .address("北京")
        .phone("123456")
        .build();

3. 工厂模式 Factory

作用

把对象创建逻辑封装起来,调用者不需要关心具体创建细节。

Android 中常见场景

  • BitmapFactory
  • LayoutInflater.from(context)
  • ViewModelProvider.Factory
  • FragmentFactory
  • ThreadFactory

示例

public class ShapeFactory {

    public static Shape createShape(String type) {
        if ("circle".equals(type)) {
            return new Circle();
        } else if ("rect".equals(type)) {
            return new Rect();
        }
        return null;
    }
}

面试常问

问:简单工厂、工厂方法、抽象工厂有什么区别?

简单理解:

类型 特点
简单工厂 一个工厂类根据参数创建不同对象
工厂方法 每个产品对应一个工厂子类
抽象工厂 创建一组相关对象

4. 观察者模式 Observer

作用

一个对象状态变化时,自动通知依赖它的对象。

Android 中常见场景

  • LiveData
  • RxJava
  • Flow
  • EventBus
  • BroadcastReceiver
  • TextWatcher
  • OnClickListener
  • RecyclerView.AdapterDataObserver

示例

button.setOnClickListener(v -> {
    // 点击事件回调
});

这其实就是一种观察者模式:

Button 是被观察者
OnClickListener 是观察者
点击事件发生后通知 listener

LiveData 示例

viewModel.userLiveData.observe(this, user -> {
    textView.setText(user.getName());
});

面试常问

问:观察者模式和发布订阅模式有什么区别?

答:

观察者模式中,观察者和被观察者通常直接关联。

Subject 持有 Observer 列表

发布订阅模式中,中间多了一个事件中心。

Publisher -> EventBus -> Subscriber

所以发布订阅模式解耦更强。


5. 适配器模式 Adapter

作用

把一个类的接口转换成客户端期望的接口。

Android 中常见场景

  • RecyclerView.Adapter
  • ListView.Adapter
  • PagerAdapter
  • FragmentStateAdapter
  • SpinnerAdapter

示例

RecyclerView.Adapter 的作用就是:

把数据 List<T> 适配成 RecyclerView 可以显示的 ViewHolder
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
    private List<User> users;
}

面试常问

问:RecyclerView.Adapter 是什么设计模式?

答:

主要是适配器模式。

它负责把数据源适配成 RecyclerView 能展示的 Item View。

同时,ViewHolder 又体现了缓存复用思想。


6. ViewHolder 模式

严格来说,ViewHolder 不一定算 GoF 经典设计模式,但 Android 面试很常见。

作用

缓存 Item 中的 View,避免频繁 findViewById(),提升列表滑动性能。

常见场景

  • ListView
  • RecyclerView

示例

static class ViewHolder extends RecyclerView.ViewHolder {
    TextView name;

    public ViewHolder(View itemView) {
        super(itemView);
        name = itemView.findViewById(R.id.tv_name);
    }
}

面试常问

问:RecyclerView 为什么比 ListView 性能更好?

答:

  1. 强制使用 ViewHolder
  2. 支持更灵活的布局管理器
  3. 支持局部刷新
  4. 支持 Item 动画
  5. 缓存机制更完善

7. 代理模式 Proxy

作用

为其他对象提供一种代理,以控制对这个对象的访问。

Android 中常见场景

  • Binder 机制中的 Proxy/Stub
  • AIDL 生成代码
  • Retrofit 动态代理
  • Hook 技术
  • ContextWrapper

AIDL 中的代理模式

客户端拿到的是远程服务的代理对象:

客户端 Proxy -> Binder 驱动 -> 服务端 Stub

客户端调用方法,看起来像普通方法调用:

service.getUserName();

实际底层是:

mRemote.transact(...)

面试常问

问:AIDL 中 Stub 和 Proxy 分别是什么?

答:

  • Stub:服务端 Binder 对象,负责接收请求并分发到具体方法。
  • Proxy:客户端代理对象,负责把方法调用转换成 Binder 的 transact()

8. 装饰者模式 Decorator

作用

在不改变原对象结构的情况下,动态增强对象功能。

Android 中常见场景

  • ContextWrapper
  • ContextThemeWrapper
  • BufferedInputStream
  • DataInputStream
  • OkHttp 中的拦截器也有类似增强思想

示例

ContextWrapper wrapper = new ContextWrapper(context);

ContextWrapper 包装了一个真实的 Context,并可以增强或修改部分行为。

面试常问

问:代理模式和装饰者模式区别?

答:

对比 代理模式 装饰者模式
目的 控制访问 增强功能
关注点 是否允许访问、远程访问、懒加载等 给对象添加新能力
例子 Binder Proxy ContextWrapper

9. 外观模式 Facade

作用

对外提供一个简单接口,隐藏内部复杂实现。

Android 中常见场景

  • Context
  • MediaPlayer
  • Glide
  • Retrofit
  • 各种 Manager 类

示例

Glide.with(context)
        .load(url)
        .into(imageView);

调用者只需要一行代码,不需要关心:

  • 网络请求
  • 图片解码
  • 缓存
  • 线程切换
  • Bitmap 复用

这些复杂逻辑都被 Glide 封装起来了。


10. 策略模式 Strategy

作用

定义一组算法,把它们封装起来,使它们可以互相替换。

Android 中常见场景

  • Interpolator
  • RecyclerView.LayoutManager
  • 图片加载策略
  • 缓存策略
  • 排序策略
  • 支付方式选择

示例

animation.setInterpolator(new AccelerateInterpolator());

不同的插值器表示不同动画变化策略:

new LinearInterpolator()
new AccelerateInterpolator()
new DecelerateInterpolator()

面试常问

问:策略模式和工厂模式有什么区别?

答:

  • 工厂模式关注“创建对象”
  • 策略模式关注“行为算法的替换”

11. 模板方法模式 Template Method

作用

父类定义算法骨架,子类实现具体步骤。

Android 中常见场景

  • Activity 生命周期
  • Fragment 生命周期
  • AsyncTask
  • 自定义 View 的绘制流程

示例

Activity 生命周期:

onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()

系统定义整体流程,开发者重写其中某些方法。

自定义 View

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 自定义绘制
}

面试常问

问:Activity 生命周期体现了什么设计模式?

答:

模板方法模式。

Android Framework 定义生命周期调用流程,开发者通过重写生命周期方法插入自己的逻辑。


12. 责任链模式 Chain of Responsibility

作用

多个对象按链式顺序处理请求,直到某个对象处理为止。

Android 中常见场景

  • View 事件分发
  • OkHttp 拦截器
  • Touch 事件传递
  • Handler 消息机制有部分链式思想

View 事件分发

Activity
  -> Window
    -> DecorView
      -> ViewGroup
        -> View

事件依次传递:

dispatchTouchEvent()
onInterceptTouchEvent()
onTouchEvent()

OkHttp 拦截器

应用拦截器
  -> 重试重定向拦截器
    -> BridgeInterceptor
      -> CacheInterceptor
        -> ConnectInterceptor
          -> CallServerInterceptor

面试常问

问:Android 事件分发是什么设计模式?

答:

主要体现责任链模式。

事件从 Activity 一层层向下分发,每一层都有机会处理或拦截事件。


13. 享元模式 Flyweight

作用

共享对象,减少内存占用。

Android 中常见场景

  • Message.obtain()
  • Handler 消息池
  • RecyclerView 复用 ItemView
  • Bitmap 缓存
  • 字符串常量池

Message 示例

Message msg = Message.obtain();

比直接:

new Message();

更好,因为 Message.obtain() 会从消息池中复用对象,减少频繁创建和 GC。

面试常问

问:Handler 的 Message 为什么推荐使用 obtain?

答:

因为 Message.obtain() 会复用消息池中的 Message 对象,减少内存分配和 GC,提高性能。


14. MVC / MVP / MVVM 架构模式

这类不属于传统 GoF 设计模式,但 Android 面试非常常见。


二、Android 架构模式

1. MVC

结构

Model:数据层
View:界面层
Controller:控制层

Android 中的问题

Activity/Fragment 往往同时承担 View 和 Controller,导致代码臃肿。

Activity 既处理 UI,又处理业务逻辑

所以容易变成:

Massive Activity

2. MVP

结构

Model:数据
View:界面接口
Presenter:业务逻辑

特点

View 和 Model 不直接通信,通过 Presenter 中转。

View <-> Presenter <-> Model

优点

  • 降低 Activity/Fragment 复杂度
  • 便于单元测试
  • 职责清晰

缺点

  • 接口类多
  • Presenter 容易膨胀
  • 生命周期处理麻烦

3. MVVM

结构

Model:数据层
View:Activity/Fragment/XML
ViewModel:状态和业务逻辑

Android 常见组合

ViewModel + LiveData/StateFlow + DataBinding/ViewBinding

特点

View 观察 ViewModel 中的数据变化。

viewModel.userLiveData.observe(this, user -> {
    textView.setText(user.name);
});

优点

  • 生命周期感知
  • UI 和数据状态分离
  • 配合 Jetpack 使用方便
  • 适合响应式开发

面试常问

问:MVP 和 MVVM 的区别?

对比 MVP MVVM
中间层 Presenter ViewModel
View 更新 Presenter 主动调用 View 接口 View 观察数据变化
生命周期 需要自己处理 ViewModel 生命周期感知
耦合 Presenter 持有 View 接口 ViewModel 不应持有 View
常用技术 接口回调 LiveData / Flow / DataBinding

三、Android 设计模式高频面试题

1. Android 中哪些地方用到了单例模式?

常见回答:

  • Application
  • Runtime
  • InputMethodManager
  • LayoutInflater.from(context) 内部缓存
  • OkHttpClient
  • Retrofit
  • 数据库管理类
  • 图片加载框架管理类

注意:

Application 本身由系统创建,通常整个 App 进程只有一个实例,但它不是我们手写的标准单例。


2. AlertDialog.Builder 用的什么模式?

答:

Builder 建造者模式。

它通过链式调用一步步设置参数,最后通过:

create()
show()

创建或显示 Dialog。


3. RecyclerView.Adapter 是什么设计模式?

答:

适配器模式。

它把数据集合适配成 RecyclerView 可以识别和展示的 ViewHolder。


4. View 事件分发是什么设计模式?

答:

责任链模式。

事件从 Activity、Window、DecorView、ViewGroup 到 View 逐层传递,每一层都可以决定是否消费或继续分发。


5. AIDL/Binder 用到了什么设计模式?

答:

主要是代理模式。

客户端拿到的是服务端 Binder 的代理对象 Proxy,方法调用会被转换成 Binder IPC 请求。

同时服务端的 Stub 负责接收请求并分发。


6. LiveData 是什么设计模式?

答:

观察者模式。

Activity/Fragment 观察 LiveData,当数据变化时,LiveData 通知观察者更新 UI。


7. BroadcastReceiver 是什么设计模式?

答:

观察者模式或发布订阅模式。

广播发送者不直接依赖接收者,系统广播机制负责分发事件。


8. OkHttp 拦截器是什么设计模式?

答:

责任链模式。

每个 Interceptor 处理请求的一部分,然后通过:

chain.proceed(request)

交给下一个拦截器。


9. Glide.with().load().into() 体现了什么模式?

可以回答:

  • 外观模式:封装复杂图片加载逻辑
  • Builder/链式调用:配置请求参数
  • 观察者/回调:监听加载结果
  • 缓存中可能用到享元思想

面试中主答:

Glide 对外提供了简单 API,隐藏内部复杂的网络、缓存、解码、线程调度流程,体现了外观模式。


10. Handler 消息机制中用到了什么设计模式?

可以回答:

  1. 享元模式:Message.obtain() 复用 Message
  2. 生产者消费者模型:发送消息和处理消息
  3. 观察者/回调思想:Handler 处理 Message 或 Runnable
  4. Looper 不一定是标准单例,但一个线程通常只有一个 Looper

四、常见设计模式速记表

设计模式 Android 典型例子
单例模式 Retrofit、OkHttpClient、RoomDatabase
Builder 模式 AlertDialog.Builder、Notification.Builder
工厂模式 BitmapFactory、LayoutInflater
观察者模式 LiveData、RxJava、OnClickListener
适配器模式 RecyclerView.Adapter、ListView.Adapter
代理模式 AIDL、Binder Proxy、Retrofit
装饰者模式 ContextWrapper、BufferedInputStream
外观模式 Glide、Retrofit、Context
策略模式 Interpolator、LayoutManager
模板方法模式 Activity 生命周期、自定义 View
责任链模式 事件分发、OkHttp Interceptor
享元模式 Message.obtain、RecyclerView 复用

五、面试回答模板

如果面试官问:

Android 中你知道哪些设计模式?

可以这样回答:

Android 中常见设计模式有很多。

比如单例模式,常用于 Retrofit、OkHttp、数据库管理类;
Builder 模式,比如 AlertDialog.Builder;
适配器模式,比如 RecyclerView.Adapter;
观察者模式,比如 LiveData、OnClickListener、BroadcastReceiver;
代理模式,比如 AIDL 中的 Stub 和 Proxy;
责任链模式,比如 View 事件分发和 OkHttp 拦截器;
模板方法模式,比如 Activity 生命周期;
享元模式,比如 Handler 的 Message.obtain();
策略模式,比如动画 Interpolator 和 RecyclerView.LayoutManager。

这些模式主要是为了解耦、复用、扩展和提高代码可维护性。

如果想加分,可以继续说:

我在项目中常用的是 MVVM 架构,ViewModel 负责保存 UI 状态,LiveData 或 StateFlow 负责数据通知,Repository 负责数据来源封装,这里面也结合了观察者模式、单例模式、工厂模式等思想。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇