Android中常用设计模式的体现
一、创建型模式
1. 单例模式(Singleton)
场景:全局唯一实例,避免重复创建
kotlin
// Kotlin实现(object关键字)
object AppConfig {
private const val TAG = "AppConfig"
fun init() {
// 初始化配置
}
}
// 双重校验锁式(Java风格)
class NetworkManager private constructor() {
companion object {
@Volatile
private var instance: NetworkManager? = null
fun getInstance(): NetworkManager {
return instance ?: synchronized(this) {
instance ?: NetworkManager().also { instance = it }
}
}
}
}
// Android中的实际应用
- Application类(整个应用只有一个实例)
- 各种Manager:LocationManager, NotificationManager
- SharedPreferences(通过getDefaultSharedPreferences获取)2. 建造者模式(Builder)
场景:复杂对象的逐步构建
kotlin
// AlertDialog.Builder(最经典的例子)
AlertDialog.Builder(context)
.setTitle("提示")
.setMessage("确定删除吗?")
.setPositiveButton("确定") { dialog, _ ->
// 处理点击
dialog.dismiss()
}
.setNegativeButton("取消", null)
.create()
.show()
// Retrofit.Builder
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpClient.Builder().build())
.build()
// Notification.Builder
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle("新消息")
.setContentText("您有一条新消息")
.setSmallIcon(R.drawable.ic_notification)
.build()3. 工厂模式(Factory)
场景:创建对象时不暴露具体实现
kotlin
// 简单工厂
object ViewFactory {
fun createView(type: String, context: Context): View {
return when (type) {
"button" -> Button(context)
"textView" -> TextView(context)
"imageView" -> ImageView(context)
else -> throw IllegalArgumentException("Unknown type")
}
}
}
// Fragment工厂(setArguments传递参数)
class UserFragment : Fragment() {
companion object {
fun newInstance(userId: String): UserFragment {
return UserFragment().apply {
arguments = bundleOf("user_id" to userId)
}
}
}
}
// Android中的实际应用
- LayoutInflater.from(context).inflate(resId, parent, attachToRoot)
- BitmapFactory.decodeResource(resources, R.drawable.image)二、结构型模式
1. 适配器模式(Adapter)
场景:接口转换,使不兼容的接口能够一起工作
kotlin
// RecyclerView.Adapter(最典型的例子)
class UserAdapter(private val users: List<User>) :
RecyclerView.Adapter<UserAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val nameTextView: TextView = view.findViewById(R.id.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.nameTextView.text = users[position].name
}
override fun getItemCount() = users.size
}
// ListView Adapter, BaseAdapter
// ArrayAdapter, CursorAdapter2. 装饰器模式(Decorator)
场景:动态扩展对象功能
kotlin
// ContextWrapper(装饰Context)
class CustomContextWrapper(base: Context) : ContextWrapper(base) {
override fun getResources(): Resources {
// 修改资源,如修改语言
return super.getResources()
}
}
// InputStream装饰器链
val inputStream = FileInputStream("file.txt")
val buffered = BufferedInputStream(inputStream) // 添加缓冲功能
val gzip = GZIPInputStream(buffered) // 添加解压功能
// View的装饰:为View添加边框、阴影等
class ShadowView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {
init {
ViewCompat.setElevation(this, 10f) // 添加阴影效果
}
}3. 外观模式(Facade)
场景:简化复杂系统的接口
kotlin
// Glide(简化图片加载的复杂流程)
Glide.with(context)
.load("https://example.com/image.jpg")
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageView)
// Retrofit(封装HTTP请求的复杂性)
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: String): User
}
// Camera API(CameraX简化了原生Camera2的复杂性)
val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
// 绑定用例
}, ContextCompat.getMainExecutor(context))4. 组合模式(Composite)
场景:树形结构,部分-整体层次结构
kotlin
// View和ViewGroup体系
// View(叶子节点)
// ViewGroup(容器节点,可包含子View)
class CustomViewGroup(context: Context) : ViewGroup(context) {
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
// 布局子View
}
}
// Drawable层次结构(LayerDrawable, StateListDrawable)
val layerDrawable = LayerListDrawable()
layerDrawable.addLayer(shapeDrawable)
layerDrawable.addLayer(bitmapDrawable)三、行为型模式
1. 观察者模式(Observer)
场景:一对多依赖,对象状态变化时通知所有依赖对象
kotlin
// LiveData(最经典的观察者模式实现)
class UserViewModel : ViewModel() {
private val _userName = MutableLiveData<String>()
val userName: LiveData<String> = _userName
fun updateName(name: String) {
_userName.value = name
}
}
// 在Activity/Fragment中观察
viewModel.userName.observe(this) { name ->
textView.text = name
}
// RxJava(响应式编程)
Observable.create<String> { emitter ->
// 发射数据
emitter.onNext("Hello")
emitter.onComplete()
}.subscribe(
{ value -> Log.d("Rx", value) }, // onNext
{ error -> Log.e("Rx", "Error", error) }, // onError
{ Log.d("Rx", "Completed") } // onComplete
)
// EventBus, BroadcastReceiver都是观察者模式2. 策略模式(Strategy)
场景:定义算法族,使算法可以互相替换
kotlin
// 动画插值器(Interpolator)
view.animate()
.translationX(100f)
.setInterpolator(AccelerateDecelerateInterpolator()) // 策略1
// .setInterpolator(BounceInterpolator()) // 策略2
// .setInterpolator(LinearInterpolator()) // 策略3
.start()
// RecyclerView的LayoutManager
recyclerView.layoutManager = LinearLayoutManager(context) // 策略1
// recyclerView.layoutManager = GridLayoutManager(context, 2) // 策略2
// recyclerView.layoutManager = StaggeredGridLayoutManager(2, VERTICAL) // 策略3
// 图片加载策略
interface ImageLoaderStrategy {
fun load(context: Context, url: String, imageView: ImageView)
}
class GlideStrategy : ImageLoaderStrategy {
override fun load(context: Context, url: String, imageView: ImageView) {
Glide.with(context).load(url).into(imageView)
}
}
class PicassoStrategy : ImageLoaderStrategy {
override fun load(context: Context, url: String, imageView: ImageView) {
Picasso.get().load(url).into(imageView)
}
}3. 模板方法模式(Template Method)
场景:定义算法骨架,子类实现具体步骤
kotlin
// AsyncTask(已废弃,但设计模式经典)
abstract class CustomAsyncTask<Params, Progress, Result> {
abstract fun doInBackground(vararg params: Params): Result
open fun onPreExecute() { /* 准备 */ }
open fun onProgressUpdate(vararg values: Progress) { /* 更新进度 */ }
open fun onPostExecute(result: Result) { /* 完成后处理 */ }
fun execute(vararg params: Params) {
onPreExecute()
val result = doInBackground(*params)
onPostExecute(result)
}
}
// Activity/Fragment生命周期
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { // 模板方法
super.onCreate(savedInstanceState) // 父类实现固定逻辑
setContentView(R.layout.activity_main) // 子类自定义
}
override fun onStart() {
super.onStart() // 必须调用super
// 自定义逻辑
}
}4. 命令模式(Command)
场景:将请求封装为对象
kotlin
// Handler/Runnable(将任务封装为Runnable对象)
val runnable = Runnable {
// 执行任务
textView.text = "更新UI"
}
handler.post(runnable) // 发送命令
// 可撤销操作(如编辑器)
interface Command {
fun execute()
fun undo()
}
class ChangeTextCommand(private val textView: TextView,
private val newText: String) : Command {
private var oldText: String = ""
override fun execute() {
oldText = textView.text.toString()
textView.text = newText
}
override fun undo() {
textView.text = oldText
}
}
// 使用命令栈实现撤销/重做
val commandStack = Stack<Command>()
commandStack.push(command)
command.execute()
// 撤销
commandStack.pop().undo()5. 责任链模式(Chain of Responsibility)
场景:多个对象处理同一请求,形成处理链
kotlin
// View的事件分发机制
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
// 1. 自己的onTouchEvent
// 2. 子View的dispatchTouchEvent
// 3. 父ViewGroup的处理
return super.dispatchTouchEvent(event)
}
// OkHttp的拦截器链(Interceptor Chain)
class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
// 处理请求
Log.d("OkHttp", "Request: ${request.url}")
val response = chain.proceed(request) // 传递给下一个拦截器
// 处理响应
Log.d("OkHttp", "Response: ${response.code}")
return response
}
}
val client = OkHttpClient.Builder()
.addInterceptor(LoggingInterceptor())
.addInterceptor(CacheInterceptor())
.addNetworkInterceptor(HeaderInterceptor())
.build()四、架构相关模式
1. MVVM模式(Model-View-ViewModel)
场景:数据驱动UI,关注点分离
kotlin
// Model(数据层)
data class User(val id: String, val name: String, val age: Int)
// ViewModel(业务逻辑层)
class UserViewModel : ViewModel() {
private val repository = UserRepository()
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
fun loadUsers() {
viewModelScope.launch {
_users.value = repository.getUsers()
}
}
}
// View(UI层)
class UserActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.users.observe(this) { users ->
// 更新UI
adapter.submitList(users)
}
viewModel.loadUsers()
}
}2. 仓库模式(Repository)
场景:统一数据源访问
kotlin
class UserRepository(
private val localDataSource: UserLocalDataSource,
private val remoteDataSource: UserRemoteDataSource
) {
suspend fun getUsers(): List<User> {
// 优先从本地获取
val localUsers = localDataSource.getUsers()
if (localUsers.isNotEmpty()) {
return localUsers
}
// 本地无数据则从网络获取
val remoteUsers = remoteDataSource.getUsers()
localDataSource.saveUsers(remoteUsers)
return remoteUsers
}
}3. 依赖注入(Dependency Injection)
场景:解耦依赖关系
kotlin
// Dagger/Hilt示例
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}
// 在ViewModel中使用
@HiltViewModel
class UserViewModel @Inject constructor(
private val apiService: ApiService,
private val repository: UserRepository
) : ViewModel() {
// 使用注入的依赖
}五、Android特有模式
1. ViewHolder模式(RecyclerView优化)
kotlin
class UserAdapter : RecyclerView.Adapter<UserAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// 缓存View引用,避免重复findViewById
val nameTextView: TextView = view.findViewById(R.id.name)
val avatarImageView: ImageView = view.findViewById(R.id.avatar)
}
}2. Binder模式(AIDL跨进程通信)
kotlin
// 定义AIDL接口
interface IUserService {
User getUserById(in String id);
void addUser(in User user);
}
// Binder负责进程间通信和数据序列化3. Loader模式(已废弃,但设计值得学习)
kotlin
// 异步加载数据,自动管理生命周期
class UserLoader(context: Context) : AsyncTaskLoader<List<User>>(context) {
override fun loadInBackground(): List<User> {
// 后台加载数据
return repository.getUsers()
}
override fun onStartLoading() {
forceLoad()
}
}六、面试要点总结
常考问题:
- MVC、MVP、MVVM的区别和优劣
- 单例模式在Android中的注意事项(内存泄漏、多进程)
- 观察者模式在Android中的多种实现
- Builder模式的优点和使用场景
- 适配器模式在RecyclerView中的应用
实际应用建议:
- 合理选择模式:不要为了用模式而用模式
- 结合Android特性:考虑生命周期、内存管理
- Kotlin简化:很多模式在Kotlin中有更简洁的实现
- 性能考虑:避免过度设计,保持代码简洁
掌握这些设计模式在Android中的体现,能帮助写出更健壮、可维护的代码,也是面试中的加分项。