事圆则缓头像
关注
Android 常用设计模式速查封面图

Android 常用设计模式速查

Android 常用设计模式速查

本文整理 Android 开发中常见技术点对应的设计模式,并给出简化伪代码、典型源码/原理使用位置。伪代码用于理解模式结构,不等同于源码实现。

总览

设计模式Android 常见技术点典型使用位置
单例模式全局管理器、系统服务、数据库实例WorkManager.getInstance()Room.databaseBuilder() 后的数据库单例、SystemServiceRegistry
Builder 模式复杂对象构建AlertDialog.BuilderNotificationCompat.BuilderRoom.databaseBuilder()
工厂模式对象创建解耦LayoutInflater.Factory2FragmentFactoryViewModelProvider.Factory
观察者模式数据变化通知、生命周期感知LiveData.observe()LifecycleObserverFlow.collect
适配器模式数据和 UI 解耦RecyclerView.AdapterListAdapterCursorAdapter
代理模式IPC、远程服务、本地接口代理Binder 的 Stub / Proxy、AIDL
装饰器模式包装并增强能力ContextWrapperContextThemeWrapperInputStream 包装链
外观模式简化复杂子系统访问ContextCameraXGlide.with()
模板方法模式固定流程中暴露可重写步骤Activity 生命周期、View.draw()ViewGroup.dispatchDraw()
策略模式可替换算法或行为RecyclerView.LayoutManagerItemAnimatorDiffUtil.ItemCallback
责任链模式事件分发、拦截链触摸事件分发、OkHttp Interceptor
状态模式对象行为随状态变化Lifecycle.State、播放器状态、登录状态
命令模式把操作封装为对象Runnable + HandlerPendingIntent、点击事件回调
MVC / MVP / MVVM应用架构分层Activity/FragmentViewModelLiveData/StateFlow、Repository

1. 单例模式 Singleton

使用场景

  • 应用内只有一个实例:数据库、配置中心、线程池、日志工具。
  • Android 系统服务通过统一入口获取共享服务。
  • 避免重复创建重资源对象。

Android 中的例子

  • WorkManager.getInstance(context)
  • RoomDatabase 通常在应用层做单例封装
  • SystemServiceRegistry 管理系统服务实例
  • Application 全局生命周期入口

伪代码

class AppDatabase private constructor() {
    companion object {
        @Volatile
        private var instance: AppDatabase? = null

        fun getInstance(): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: AppDatabase().also { instance = it }
            }
        }
    }
}

源码 / 原理标注

  • Context.getSystemService() 背后会从系统服务注册表中按名称获取服务。
  • WorkManager 通过 getInstance() 对外提供统一入口,内部保证调度组件可被全局访问。
  • Room 数据库实例创建成本较高,官方实践通常建议在应用进程内复用单例。

2. Builder 模式

使用场景

  • 对象参数很多,构造函数会变得臃肿。
  • 创建过程需要链式配置。
  • 最终通过 build()create() 生成目标对象。

Android 中的例子

  • AlertDialog.Builder
  • NotificationCompat.Builder
  • Room.databaseBuilder(context, AppDatabase::class.java, "db").build()
  • WorkRequest.Builder

伪代码

class Dialog private constructor(
    val title: String?,
    val message: String?,
    val cancelable: Boolean
) {
    class Builder {
        private var title: String? = null
        private var message: String? = null
        private var cancelable: Boolean = true

        fun setTitle(value: String) = apply { title = value }
        fun setMessage(value: String) = apply { message = value }
        fun setCancelable(value: Boolean) = apply { cancelable = value }

        fun build(): Dialog {
            return Dialog(title, message, cancelable)
        }
    }
}

源码 / 原理标注

  • AlertDialog.Builder 先收集标题、按钮、布局等配置,最后调用 create() 构建 AlertDialog
  • NotificationCompat.Builder 把通知图标、标题、内容、渠道等复杂参数集中封装,降低构造复杂度。
  • Room 的 builder 会配置数据库名、迁移策略、线程策略,最后创建数据库实例。

3. 工厂模式 Factory

使用场景

  • 调用方不直接依赖具体类构造函数。
  • 根据条件创建不同对象。
  • 框架希望把对象创建权开放给开发者定制。

Android 中的例子

  • LayoutInflater.Factory2 创建 View
  • FragmentFactory 创建 Fragment
  • ViewModelProvider.Factory 创建 ViewModel
  • ServiceLoader 或依赖注入框架中的对象创建

伪代码

interface ViewModelFactory {
    fun <T : ViewModel> create(modelClass: Class<T>): T
}

class UserViewModelFactory(
    private val repository: UserRepository
) : ViewModelFactory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass == UserViewModel::class.java) {
            return UserViewModel(repository) as T
        }
        error("Unknown ViewModel")
    }
}

源码 / 原理标注

  • ViewModelProvider 不知道业务 ViewModel 如何构造,于是通过 Factory 把创建过程交给调用方。
  • LayoutInflater 解析 XML 时,需要把标签名转换成具体 View 对象,这就是典型的创建型模式场景。
  • FragmentFactory 允许 Fragment 使用带参数构造或依赖注入方式创建,避免框架只能调用空构造。

4. 观察者模式 Observer

使用场景

  • 一个对象状态变化,需要通知多个观察者。
  • UI 自动响应数据变化。
  • 生命周期变化需要通知监听者。

Android 中的例子

  • LiveData.observe(owner, observer)
  • Lifecycle.addObserver(observer)
  • StateFlow / SharedFlow
  • TextWatcherBroadcastReceiver

伪代码

class ObservableData<T> {
    private val observers = mutableListOf<(T) -> Unit>()
    private var value: T? = null

    fun observe(observer: (T) -> Unit) {
        observers += observer
        value?.let(observer)
    }

    fun setValue(newValue: T) {
        value = newValue
        observers.forEach { it(newValue) }
    }
}

源码 / 原理标注

  • LiveData 保存观察者列表,数据变化后分发给活跃生命周期状态下的观察者。
  • LifecycleRegistry 内部维护观察者,并在 Activity / Fragment 生命周期变化时派发生命周期事件。
  • BroadcastReceiver 可以理解为系统级发布订阅机制,发送广播后匹配的接收者会收到通知。

5. 适配器模式 Adapter

使用场景

  • 将一种接口转换成另一种接口。
  • 数据结构和 UI 展示组件不直接耦合。
  • 让已有数据适配目标控件协议。

Android 中的例子

  • RecyclerView.Adapter
  • ListAdapter
  • CursorAdapter
  • PagerAdapter

伪代码

class UserAdapter(
    private val users: List<User>
) : RecyclerView.Adapter<UserViewHolder>() {

    override fun getItemCount(): Int {
        return users.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        return UserViewHolder(parent.inflate("item_user"))
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        holder.bind(users[position])
    }
}

源码 / 原理标注

  • RecyclerView 不关心数据来源,只依赖 Adapter 提供数量、创建 ViewHolder、绑定数据。
  • CursorAdapter 把数据库查询结果 Cursor 适配成列表项视图。
  • ListAdapter 在适配器基础上加入 DiffUtil,让列表更新更高效。

6. 代理模式 Proxy

使用场景

  • 调用方访问的是代理对象,代理对象再转发给真实对象。
  • 可以隐藏跨进程、远程、权限校验、缓存等复杂细节。
  • Android IPC 是代理模式的经典场景。

Android 中的例子

  • Binder IPC 中的 StubProxy
  • AIDL 自动生成代码
  • 系统服务接口,例如 ActivityManagerPackageManager

伪代码

interface IUserService {
    fun getUserName(id: Long): String
}

class UserServiceProxy(
    private val remoteBinder: Binder
) : IUserService {
    override fun getUserName(id: Long): String {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        data.writeLong(id)
        remoteBinder.transact(CODE_GET_USER, data, reply, 0)
        return reply.readString()
    }
}

源码 / 原理标注

  • AIDL 会生成 StubProxy:本地进程调用接口方法,实际由 Proxy 封装参数并通过 Binder 发送到远端。
  • 客户端拿到的很多系统服务接口并不是真实服务对象,而是 Binder 代理。
  • Proxy 屏蔽了进程边界,让跨进程调用看起来像普通方法调用。

7. 装饰器模式 Decorator

使用场景

  • 不修改原类的情况下增强对象能力。
  • 多层包装,逐步叠加功能。
  • 保持原始接口一致。

Android 中的例子

  • ContextWrapper
  • ContextThemeWrapper
  • Java IO 中的 BufferedInputStream(InputStream)
  • AppCompat 中对 ContextView 的包装增强

伪代码

open class BaseContext {
    open fun getThemeName(): String = "Default"
}

open class ContextWrapper(
    private val base: BaseContext
) : BaseContext() {
    override fun getThemeName(): String {
        return base.getThemeName()
    }
}

class ThemeContextWrapper(
    base: BaseContext,
    private val theme: String
) : ContextWrapper(base) {
    override fun getThemeName(): String {
        return theme
    }
}

源码 / 原理标注

  • ContextWrapper 内部持有一个 base Context,默认把大部分调用委托给它。
  • ContextThemeWrapper 在原有 Context 基础上叠加主题能力。
  • Activity 本身也继承自 ContextThemeWrapper,因此具备上下文和主题相关能力。

8. 外观模式 Facade

使用场景

  • 对外暴露简单接口,内部封装复杂子系统。
  • 降低调用方理解成本。
  • 常用于 SDK、框架入口、工具库入口。

Android 中的例子

  • Context 封装资源、文件、服务、启动组件等能力
  • Glide.with(context).load(url).into(imageView)
  • CameraX 相比 Camera2 提供更简单的相机 API
  • NavController 封装 Fragment 事务和回退栈

伪代码

class ImageLoaderFacade(
    private val cache: ImageCache,
    private val network: ImageNetwork,
    private val decoder: ImageDecoder
) {
    fun load(url: String, imageView: ImageView) {
        val bytes = cache.get(url) ?: network.download(url)
        val bitmap = decoder.decode(bytes)
        imageView.setImageBitmap(bitmap)
    }
}

源码 / 原理标注

  • Context 是 Android 应用访问系统能力的重要外观,调用方无需知道资源管理器、包管理器、服务管理器的内部细节。
  • CameraX 把 Camera2 中复杂的设备枚举、Session、CaptureRequest 封装成更容易使用的用例 API。
  • NavController 把导航图、参数、Fragment 切换、返回栈管理封装成统一入口。

9. 模板方法模式 Template Method

使用场景

  • 父类定义算法骨架。
  • 子类只重写流程中的部分步骤。
  • 框架控制整体流程,业务代码填充细节。

Android 中的例子

  • Activity.onCreate()onStart()onResume()
  • Fragment 生命周期
  • View.draw() 中的测量、绘制、子 View 绘制流程
  • BaseAdapter.getView()

伪代码

abstract class BaseActivity {
    fun performCreate() {
        attachBaseContext()
        onCreate()
        restoreState()
    }

    protected open fun attachBaseContext() {}
    protected abstract fun onCreate()
    protected open fun restoreState() {}
}

class MainActivity : BaseActivity() {
    override fun onCreate() {
        setContentView("activity_main")
    }
}

源码 / 原理标注

  • Android Framework 决定生命周期调用顺序,开发者只重写指定回调。
  • View.draw() 内部大致按背景、内容、子 View、前景等步骤绘制,子类可重写 onDraw() 填充自定义绘制。
  • 模板方法体现了“框架调用业务代码”的控制反转思想。

10. 策略模式 Strategy

使用场景

  • 同一个上下文中切换不同算法或行为。
  • 行为对象可以独立替换。
  • 减少大量 if else

Android 中的例子

  • RecyclerView.LayoutManager
  • RecyclerView.ItemAnimator
  • DiffUtil.ItemCallback
  • 动画插值器 Interpolator

伪代码

interface SortStrategy {
    fun sort(items: List<Item>): List<Item>
}

class TimeSortStrategy : SortStrategy {
    override fun sort(items: List<Item>) = items.sortedBy { it.time }
}

class NameSortStrategy : SortStrategy {
    override fun sort(items: List<Item>) = items.sortedBy { it.name }
}

class ItemController(
    private var strategy: SortStrategy
) {
    fun render(items: List<Item>) {
        show(strategy.sort(items))
    }
}

源码 / 原理标注

  • RecyclerView 通过替换 LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager 改变布局策略。
  • Interpolator 决定动画数值随时间变化的策略,例如线性、加速、减速。
  • DiffUtil.ItemCallback 把“如何判断两个 item 是否相同”的策略交给业务层。

11. 责任链模式 Chain of Responsibility

使用场景

  • 请求沿着一条链传递。
  • 链上每个节点都有机会处理或继续传递。
  • 常用于事件分发、请求拦截、日志处理。

Android 中的例子

  • 触摸事件分发:Activity -> Window -> DecorView -> ViewGroup -> View
  • ViewGroup.dispatchTouchEvent()onInterceptTouchEvent()onTouchEvent()
  • OkHttp Interceptor 拦截器链

伪代码

abstract class EventNode {
    var next: EventNode? = null

    fun dispatch(event: MotionEvent): Boolean {
        if (handle(event)) {
            return true
        }
        return next?.dispatch(event) ?: false
    }

    protected abstract fun handle(event: MotionEvent): Boolean
}

源码 / 原理标注

  • 触摸事件先到 Activity.dispatchTouchEvent(),再进入 Window 和根 View。
  • ViewGroup 可以通过 onInterceptTouchEvent() 决定是否拦截事件。
  • 如果子 View 不消费事件,事件可能回到父容器或自身的 onTouchEvent() 继续处理。
  • OkHttp 的应用拦截器、重试拦截器、缓存拦截器、网络拦截器按链式顺序处理请求。

12. 状态模式 State

使用场景

  • 对象在不同状态下行为不同。
  • 状态转换规则比较清晰。
  • 避免状态相关逻辑散落在多个条件分支中。

Android 中的例子

  • Lifecycle.State
  • 播放器状态:Idle、Preparing、Playing、Paused、Completed
  • 登录状态:Guest、LoggedIn、Expired
  • 下载任务状态:Pending、Running、Success、Failed

伪代码

interface PlayerState {
    fun play(player: Player)
    fun pause(player: Player)
}

class IdleState : PlayerState {
    override fun play(player: Player) {
        player.prepare()
        player.state = PlayingState()
    }

    override fun pause(player: Player) {
        // Idle 状态下无需处理
    }
}

class PlayingState : PlayerState {
    override fun play(player: Player) {}

    override fun pause(player: Player) {
        player.pauseInternal()
        player.state = PausedState()
    }
}

源码 / 原理标注

  • LifecycleRegistry 会在生命周期事件发生时推进内部状态,例如 INITIALIZEDCREATEDSTARTEDRESUMED
  • UI 层常用状态驱动渲染,例如 Loading、Content、Empty、Error。
  • 播放器、下载器、上传器这类组件很适合用状态模式管理行为。

13. 命令模式 Command

使用场景

  • 把一个操作封装成对象。
  • 操作可以延迟执行、排队执行、撤销或重试。
  • 调用者和执行者解耦。

Android 中的例子

  • Runnable 投递到 Handler
  • PendingIntent
  • View.OnClickListener
  • WorkRequest

伪代码

interface Command {
    fun execute()
}

class SaveUserCommand(
    private val repository: UserRepository,
    private val user: User
) : Command {
    override fun execute() {
        repository.save(user)
    }
}

class CommandQueue {
    private val commands = ArrayDeque<Command>()

    fun enqueue(command: Command) {
        commands.addLast(command)
    }

    fun runNext() {
        commands.removeFirstOrNull()?.execute()
    }
}

源码 / 原理标注

  • Handler.post(Runnable) 把一段逻辑封装为 Runnable,放入消息队列等待主线程或工作线程执行。
  • PendingIntent 把未来要执行的启动 Activity、Service、Broadcast 操作交给系统保存并触发。
  • WorkRequest 把后台任务的执行条件、输入数据、调度要求封装起来,由 WorkManager 统一执行。

14. MVC / MVP / MVVM 架构模式

使用场景

  • 组织应用层代码职责。
  • 降低 UI、业务逻辑、数据源之间的耦合。
  • 提高可测试性和可维护性。

Android 中的例子

  • MVC:早期 Activity 同时承担 Controller 和部分 View 职责。
  • MVP:Activity/Fragment 作为 View,Presenter 处理业务逻辑。
  • MVVM:ViewModel 暴露状态,Activity/Fragment/Compose 负责渲染。
  • Repository:隔离网络、数据库、缓存等数据来源。

伪代码

class UserViewModel(
    private val repository: UserRepository
) : ViewModel() {
    private val _uiState = MutableStateFlow<UserUiState>(UserUiState.Loading)
    val uiState: StateFlow<UserUiState> = _uiState

    fun loadUser(id: Long) {
        viewModelScope.launch {
            _uiState.value = UserUiState.Loading
            _uiState.value = runCatching {
                repository.getUser(id)
            }.fold(
                onSuccess = { UserUiState.Content(it) },
                onFailure = { UserUiState.Error(it.message.orEmpty()) }
            )
        }
    }
}

class UserFragment : Fragment() {
    private val viewModel: UserViewModel by viewModels()

    fun render() {
        collect(viewModel.uiState) { state ->
            when (state) {
                is UserUiState.Loading -> showLoading()
                is UserUiState.Content -> showUser(state.user)
                is UserUiState.Error -> showError(state.message)
            }
        }
    }
}

源码 / 原理标注

  • ViewModel 生命周期长于配置变化后的 Activity/Fragment 重建,适合保存 UI 状态。
  • LiveData / StateFlow 让 View 观察状态变化,体现观察者模式。
  • Repository 隔离数据来源,让 UI 层不直接依赖 Retrofit、Room、DataStore 等具体实现。
  • Jetpack Compose 中常见的 State -> UI 思路也是 MVVM / 单向数据流思想的延伸。

15. 组合模式 Composite

使用场景

  • 树形结构中,单个对象和组合对象使用统一接口。
  • 调用方可以一致地处理叶子节点和容器节点。

Android 中的例子

  • ViewViewGroup
  • 菜单结构 Menu / MenuItem
  • Compose UI 树

伪代码

abstract class UiNode {
    abstract fun draw()
}

class TextNode : UiNode() {
    override fun draw() {
        drawText()
    }
}

class ContainerNode : UiNode() {
    private val children = mutableListOf<UiNode>()

    fun add(child: UiNode) {
        children += child
    }

    override fun draw() {
        children.forEach { it.draw() }
    }
}

源码 / 原理标注

  • ViewGroup 继承自 View,因此容器本身也是一个 View。
  • ViewGroup 内部持有子 View 列表,测量、布局、绘制时会递归处理子节点。
  • Compose 运行时维护 UI 组合树,状态变化后按树结构进行重组和更新。

16. 享元模式 Flyweight

使用场景

  • 大量相似对象共享内部状态,减少内存开销。
  • 缓存可复用对象。
  • 图片、字符串、资源对象等都可能用到共享思想。

Android 中的例子

  • Bitmap 缓存
  • RecyclerView 复用 ViewHolder
  • 资源系统复用 DrawableColorStateList 等资源数据
  • 字符串常量池

伪代码

class BitmapPool {
    private val cache = mutableMapOf<String, Bitmap>()

    fun get(key: String, loader: () -> Bitmap): Bitmap {
        return cache[key] ?: loader().also { bitmap ->
            cache[key] = bitmap
        }
    }
}

源码 / 原理标注

  • RecyclerView 通过回收池复用 ViewHolder,避免列表滑动时频繁创建 View。
  • 图片加载库通常使用内存缓存、磁盘缓存、Bitmap 池降低内存抖动。
  • Android 资源加载系统会缓存部分资源,避免重复解析和创建。

记忆方式

你在做什么常见模式
创建复杂对象Builder
控制对象唯一Singleton
把创建权交出去Factory
数据变了通知 UIObserver
数据接到列表控件Adapter
跨进程像本地调用Proxy
包一层增强功能Decorator
给复杂系统一个简单入口Facade
框架定流程,业务填步骤Template Method
替换算法或行为Strategy
请求一路传递Chain of Responsibility
不同状态不同行为State
操作排队或延迟执行Command
树形 UI 统一处理Composite
大量对象共享复用Flyweight

学习建议

  • 看源码时先问:这个类是在创建对象、转发调用、分发事件、保存状态,还是适配数据?
  • Android Framework 很多模式不是“标准教科书写法”,而是为了生命周期、IPC、UI 树、线程模型做了工程化变体。
  • 面试回答时建议按“三段式”:先说模式定义,再说 Android 例子,最后说源码或原理中的关键调用链。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/z_zT_T/article/details/164333924

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--