设计模式是解决软件设计问题的经典方案,在 Android 开发中合理使用设计模式能显著提升代码的可维护性、扩展性和可读性。以下是 Android 开发中 高频使用的 8 种设计模式,结合实际场景解析其核心思想和代码实现。
一、单例模式(Singleton)
核心思想 :确保一个类只有一个实例,并提供全局访问点。
适用场景:全局配置管理、日志工具、数据库客户端等。
kotlin
// 双重校验锁单例(线程安全)
class AppConfig private constructor() {
companion object {
@Volatile private var instance: AppConfig? = null
fun getInstance(): AppConfig =
instance ?: synchronized(this) {
instance ?: AppConfig().also { instance = it }
}
}
var themeColor: String = "#4CAF50"
}
// 使用
AppConfig.getInstance().themeColor = "#2196F3"
注意事项:
- 避免内存泄漏(单例中不要持有
Activity
或View
的引用)。 - 优先使用依赖注入框架(如 Hilt/Dagger)替代手动单例。
二、观察者模式(Observer)
核心思想 :定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象自动更新。
适用场景:数据与 UI 的绑定、事件总线、实时数据更新。
kotlin
// 基于 LiveData 的观察者模式(Android Jetpack)
class UserViewModel : ViewModel() {
private val _userName = MutableLiveData<String>()
val userName: LiveData<String> = _userName
fun updateName(name: String) {
_userName.value = name
}
}
// Activity 中观察
userViewModel.userName.observe(this) { name ->
textView.text = name
}
注意事项:
- 使用
LiveData
替代传统观察者,自动处理生命周期。 - 避免在观察者回调中执行耗时操作。
三、工厂模式(Factory)
核心思想 :将对象的创建逻辑封装到子类或独立类中,客户端无需关心具体实现。
适用场景:网络请求库的创建、不同数据源的解析器。
kotlin
// 抽象工厂模式
interface ImageLoader {
fun load(url: String)
}
class GlideLoader : ImageLoader {
override fun load(url: String) { /* Glide 实现 */ }
}
class PicassoLoader : ImageLoader {
override fun load(url: String) { /* Picasso 实现 */ }
}
object ImageLoaderFactory {
fun create(type: String): ImageLoader =
when (type) {
"glide" -> GlideLoader()
"picasso" -> PicassoLoader()
else -> throw IllegalArgumentException("Unknown loader")
}
}
// 使用
val loader = ImageLoaderFactory.create("glide")
loader.load("https://example.com/image.jpg")
注意事项:
- 结合依赖注入框架,避免工厂类膨胀。
- 优先使用
@Binds
和@Provides
(Dagger/Hilt)实现工厂逻辑。
四、建造者模式(Builder)
核心思想 :将复杂对象的构造过程拆解为多个步骤,允许灵活组合参数。
适用场景 :配置复杂对象(如 AlertDialog
、网络请求配置)。
kotlin
class DialogBuilder {
private var title: String = ""
private var message: String = ""
fun setTitle(title: String) = apply { this.title = title }
fun setMessage(message: String) = apply { this.message = message }
fun build(): AlertDialog {
return AlertDialog.Builder(context)
.setTitle(title)
.setMessage(message)
.create()
}
}
// 使用
val dialog = DialogBuilder()
.setTitle("提示")
.setMessage("确认删除吗?")
.build()
dialog.show()
注意事项:
- Android 中的
AlertDialog
本身已使用建造者模式。 - 优先使用 Kotlin 的
apply
和also
简化链式调用。
五、适配器模式(Adapter)
核心思想 :将一个类的接口转换为客户端期望的另一个接口。
适用场景 :RecyclerView.Adapter
、第三方库接口兼容。
kotlin
// RecyclerView 适配器
class UserAdapter(private val users: List<User>) : RecyclerView.Adapter<UserAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(user: User) {
itemView.textView.text = user.name
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(users[position])
}
override fun getItemCount() = users.size
}
注意事项:
- 使用
ListAdapter
和DiffUtil
优化数据更新。 - 避免在
onBindViewHolder
中执行耗时操作。
六、代理模式(Proxy)
核心思想 :为其他对象提供一个代理以控制对该对象的访问。
适用场景:延迟加载图片、权限检查、网络请求拦截。
kotlin
// 图片加载代理(检查缓存)
interface ImageLoader {
fun load(url: String)
}
class RealImageLoader : ImageLoader {
override fun load(url: String) { /* 实际加载逻辑 */ }
}
class ImageLoaderProxy : ImageLoader {
private val realLoader = RealImageLoader()
private val cache = mutableMapOf<String, Bitmap>()
override fun load(url: String) {
if (cache.containsKey(url)) {
// 显示缓存图片
} else {
realLoader.load(url)
// 将结果存入缓存
}
}
}
注意事项:
- Retrofit 和 Glide 等库内部大量使用代理模式。
- 优先使用 Kotlin 的
by
关键字实现委托。
七、策略模式(Strategy)
核心思想 :定义一系列算法,使其可以相互替换,且算法的变化独立于客户端。
适用场景:支付方式选择、数据加密算法切换。
kotlin
interface PaymentStrategy {
fun pay(amount: Double)
}
class AlipayStrategy : PaymentStrategy {
override fun pay(amount: Double) { /* 支付宝支付逻辑 */ }
}
class WechatPayStrategy : PaymentStrategy {
override fun pay(amount: Double) { /* 微信支付逻辑 */ }
}
class PaymentProcessor(private val strategy: PaymentStrategy) {
fun processPayment(amount: Double) {
strategy.pay(amount)
}
}
// 使用
val processor = PaymentProcessor(AlipayStrategy())
processor.processPayment(100.0)
注意事项:
- 结合工厂模式动态创建策略对象。
- 使用
@Module
和@Binds
(Dagger/Hilt)管理策略依赖。
八、MVVM 模式(Model-View-ViewModel)
核心思想 :分离 UI 逻辑与业务逻辑,通过数据绑定实现响应式 UI。
适用场景:复杂 UI 交互、数据驱动视图更新。
kotlin
// ViewModel(业务逻辑)
class UserViewModel : ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
fun loadUsers() {
viewModelScope.launch {
_users.value = userRepository.fetchUsers()
}
}
}
// Activity/Fragment(视图层)
userViewModel.users.observe(this) { users ->
adapter.submitList(users)
}
注意事项:
- 使用
DataBinding
或ViewBinding
简化 UI 更新。 - 通过
LiveData
和StateFlow
实现单向数据流。
九、如何选择设计模式?
场景 | 推荐模式 | 示例 |
---|---|---|
全局共享配置 | 单例模式 | 应用主题、数据库客户端 |
数据与 UI 同步更新 | 观察者模式 | LiveData 监听、事件总线 |
动态创建对象 | 工厂模式 | Retrofit 实例化、图片加载器选择 |
复杂参数配置 | 建造者模式 | AlertDialog 配置、网络请求构建器 |
接口兼容与转换 | 适配器模式 | RecyclerView 适配器、第三方 SDK 封装 |
控制对象访问 | 代理模式 | 权限检查、缓存代理 |
算法灵活切换 | 策略模式 | 支付方式、数据加密算法 |
分离 UI 与业务逻辑 | MVVM 模式 | Jetpack ViewModel + LiveData |
十、总结
- 避免过度设计:优先使用 Android Jetpack 组件(如 ViewModel、LiveData)内置的模式实现。
- 组合使用模式:例如 MVVM + 观察者 + 仓库模式构建稳健架构。
- 测试驱动:通过单元测试验证模式实现的正确性和扩展性。
- 关注性能:避免在单例或观察者中持有生命周期敏感对象的引用。