
一、创建型模式
1. 单例模式 Singleton
Android 场景 :Application 实例、Room 数据库、Retrofit 客户端、SharedPreferences 封装。
实现:
java
// 方式一:静态内部类(推荐,线程安全 + 懒加载)
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
// 方式二:DCL 双重检查锁
public class SingletonDCL {
private volatile static SingletonDCL instance;
public static SingletonDCL getInstance() {
if (instance == null) {
synchronized (SingletonDCL.class) {
if (instance == null) {
instance = new SingletonDCL();
}
}
}
return instance;
}
}
// 方式三:枚举(最简洁,防反射/序列化破坏)
public enum SingletonEnum {
INSTANCE;
public void doSomething() { }
}
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 全局唯一,节省内存 | 生命周期难管理(易内存泄漏) |
| 避免重复初始化开销 | 单元测试困难(全局状态污染) |
| 访问方便 | 多线程安全问题(需 DCL 或静态内部类) |
2. 工厂模式 Factory
Android 场景:ViewModelProvider.Factory、FragmentFactory、LayoutInflater 创建 View。
java
// 工厂接口
public interface ViewModelFactory {
<T extends ViewModel> T create(Class<T> clazz);
}
// 具体工厂
public class MyViewModelFactory implements ViewModelFactory {
private Repository repo;
public MyViewModelFactory(Repository repo) {
this.repo = repo;
}
@Override
public <T extends ViewModel> T create(Class<T> clazz) {
if (clazz.isAssignableFrom(MyViewModel.class)) {
return (T) new MyViewModel(repo);
}
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
// 使用
MyViewModelFactory factory = new MyViewModelFactory(repo);
MyViewModel vm = new ViewModelProvider(owner, factory)
.get(MyViewModel.class);
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 解耦对象创建与使用 | 增加类数量 |
| 新增类型无需改调用方 | 简单场景过度设计 |
| 隐藏创建复杂度 |
3. 建造者模式 Builder
Android 场景:AlertDialog.Builder、Notification.Builder、OkHttpClient.Builder。
java
public class Person {
private final String name;
private final int age;
private final String address;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
// 建造者内部类
public static class Builder {
private String name;
private int age;
private String address;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Person build() {
return new Person(this);
}
}
}
// 使用
Person person = new Person.Builder()
.name("Tom")
.age(25)
.address("Beijing")
.build();
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 链式调用可读性强 | 代码量增加 |
| 可选参数灵活配置 | 参数少时没必要 |
| 分离构建与表示 |
4. 依赖注入 DI
Android 场景:Dagger2、Hilt。
java
// Module 提供依赖
@Module
public class NetworkModule {
@Provides
@Singleton
public Retrofit provideRetrofit() {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
// 注入使用
public class MyActivity extends AppCompatActivity {
@Inject
Repository repository;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerAppComponent.create().inject(this);
// repository 已自动注入
}
}
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 自动管理生命周期 | 学习成本高 |
| Mock 替换方便测试 | 编译时间增加 |
| 编译期检查依赖完整性 | 调试困难(生成代码不透明) |
二、结构型模式
5. 适配器模式 Adapter
Android 场景:RecyclerView.Adapter、ListAdapter、SpinnerAdapter。
java
public class MyAdapter extends ListAdapter<Item, MyAdapter.ViewHolder> {
public MyAdapter() {
super(new DiffCallback());
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(getItem(position));
}
static class ViewHolder extends RecyclerView.ViewHolder {
// ...
void bind(Item item) {
textView.setText(item.getTitle());
}
}
}
// 使用
recyclerView.setAdapter(new MyAdapter());
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 复用现有类 | 增加中间层 |
| 数据与视图解耦 | 过度适配导致混乱 |
| 统一接口规范 |
6. 装饰器模式 Decorator
Android 场景:ContextWrapper(ThemeWrapper、MutableContextWrapper)、InputStream 包装。
java
// ContextWrapper 包装 Context
public class MyContextWrapper extends ContextWrapper {
public MyContextWrapper(Context base) {
super(base);
}
@Override
public Resources getResources() {
return customResources; // 动态替换主题/资源
}
}
// 使用:原有功能保留,新增功能叠加
Context wrapped = new MyContextWrapper(context);
// InputStream 装饰器(层层包装)
InputStream bis = new BufferedInputStream(
new FileInputStream(file));
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 运行时动态扩展 | 嵌套过多难调试 |
| 符合开闭原则 | 对象层级复杂 |
| 比继承更灵活 |
三、行为型模式
7. 观察者模式 Observer
Android 场景:LiveData、RxJava、BroadcastReceiver、OnClickListener。
java
// LiveData 观察者
MutableLiveData<String> liveData = new MutableLiveData<>();
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String value) {
textView.setText(value);
}
});
// 自定义观察者(Java 7 风格)
public interface DataObserver {
void onDataChanged(Data data);
}
public class DataSubject {
private List<DataObserver> observers = new ArrayList<>();
public void register(DataObserver observer) {
observers.add(observer);
}
public void unregister(DataObserver observer) {
observers.remove(observer);
}
public void notify(Data data) {
for (DataObserver observer : observers) {
observer.onDataChanged(data);
}
}
}
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 自动响应数据变化 | 生命周期管理复杂 |
| UI 与数据解耦 | 通知链过长性能差 |
| 一对多广播 | 循环引用风险(需弱引用) |
8. 策略模式 Strategy
Android 场景:动画插值器(Interpolator)、排序策略、图片加载策略。
java
// 策略接口
public interface Interpolator {
float getInterpolation(float input);
}
// 具体策略
public class LinearInterpolator implements Interpolator {
@Override
public float getInterpolation(float input) {
return input;
}
}
public class BounceInterpolator implements Interpolator {
@Override
public float getInterpolation(float t) {
// 弹跳算法
if (t < 0.3535f) {
return bounce(t);
} else if (t < 0.7408f) {
return bounce(t - 0.54719f) + 0.7f;
}
return bounce(t - 0.8526f) + 0.9f;
}
private float bounce(float t) {
return t * t * 8.0f;
}
}
// 使用
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", 0f, 100f);
anim.setInterpolator(new BounceInterpolator());
anim.setDuration(300);
anim.start();
| ✅ 好处 | ❌ 坏处 |
|---|---|
| 消除条件分支(if-else) | 类数量增加 |
| 算法独立扩展 | 客户端需知道策略 |
| 运行时切换 |
9. 代理模式 Proxy
Android 场景:AIDL 跨进程通信(Binder 代理)、Retrofit 动态代理。
kotlin
// Retrofit 动态代理创建 API 接口
val api = Retrofit.Builder()
.baseUrl(BASE_URL)
.build()
.create(ApiService::class.java) // 动态代理生成实现类
四、核心选择原则
- 优先组合优于继承 --- 装饰器、策略模式
- 面向接口编程 --- 工厂、策略、适配器
- 单一职责原则 --- 每个类只做一件事
- 开闭原则 --- 对扩展开放,对修改关闭
- 模式是工具不是目的 --- 避免过度设计,简单场景直接写