Android随笔-常用的设计模式

一、创建型模式

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)  // 动态代理生成实现类

四、核心选择原则

  1. 优先组合优于继承 --- 装饰器、策略模式
  2. 面向接口编程 --- 工厂、策略、适配器
  3. 单一职责原则 --- 每个类只做一件事
  4. 开闭原则 --- 对扩展开放,对修改关闭
  5. 模式是工具不是目的 --- 避免过度设计,简单场景直接写
相关推荐
apihz2 小时前
台风实时与历史详情查询免费 API 接口完整教程
android·开发语言·tcp/ip·dubbo·台风·天气预报
浪客川3 小时前
AOSP源码隐藏状态栏
android·aosp
ttod_qzstudio3 小时前
【软考设计模式】装饰模式:“套娃“式增强与动态职责扩展精讲
设计模式·装饰模式
没有了遇见3 小时前
AI Agent 是什么?—— 一文理解 LLM、Memory、Skills、Tools、MCP、Workflow,Context
android·前端·程序员
御坂嘀喵4 小时前
Speed Tools:一套低侵入的 Android 插件化 + 动态换肤 + 字体切换框架
android·gitee
浮江雾4 小时前
Flutter第三节----Dart中的数据类型
android·开发语言·学习·flutter·入门·函数
烬羽4 小时前
MCP 多服务器架构实战:一个 Agent 同时操控地图、浏览器和文件
设计模式·设计
风和先行4 小时前
Android 数据库相关学习总结
android·数据库·学习
杉氧5 小时前
Compose 渲染内核 (3):Slot Table 与 Gap Buffer —— 极速重组的数学艺术
android·架构·android jetpack
阿巴斯甜5 小时前
ContentObserver的使用:
android