Android/Java 中创建类实例的各种模式
📋 创建型模式总览
模式名称 | 核心思想 | 使用频率 | 难度 |
---|---|---|---|
new 关键字 | 直接调用构造函数 | ⭐⭐⭐⭐⭐ | ⭐ |
静态工厂方法 | 通过静态方法创建实例 | ⭐⭐⭐⭐ | ⭐⭐ |
建造者模式 | 分步构建复杂对象 | ⭐⭐⭐ | ⭐⭐⭐ |
单例模式 | 确保全局唯一实例 | ⭐⭐⭐⭐ | ⭐⭐ |
依赖注入 | 外部容器管理依赖 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
抽象工厂模式 | 创建相关对象家族 | ⭐⭐ | ⭐⭐⭐⭐ |
原型模式 | 通过克隆创建实例 | ⭐ | ⭐⭐⭐ |
反射创建 | 运行时动态创建 | ⭐ | ⭐⭐⭐⭐ |
1. new 关键字 (Direct Instantiation)
📖 名词解释
最基础的实例创建方式,直接调用类的构造函数来创建对象实例。
🎯 核心特点
// 基本语法
ClassName object = new ClassName(arguments);// 示例
User user = new User("Alice", 25);
TextView textView = new TextView(context);
✅ 优点
- 简单直观:语法简单,学习成本低
- 性能最佳:没有额外的开销,直接调用构造函数
- 编译时检查:类型安全,编译时就能发现错误
- 明确性:代码意图清晰,易于理解
❌ 缺点
- 紧耦合:客户端代码直接依赖具体实现类
- 缺乏灵活性:无法在创建过程中加入额外逻辑
- 难以测试:难以替换为Mock对象进行单元测试
- 构造函数膨胀:参数过多时代码难以维护
🎯 适用场景
- 简单的数据对象(POJO、DTO)
- 在类内部创建辅助工具对象
- 性能要求极高的场景
- 原型开发或一次性代码
🔍 Android 示例
// 创建基础UI组件
TextView textView = new TextView(context);
Button button = new Button(context);// 创建数据对象
Intent intent = new Intent(context, MainActivity.class);
Bundle bundle = new Bundle();
2. 静态工厂方法 (Static Factory Method)
📖 名词解释
通过类的静态方法来创建实例,而不是直接调用构造函数。
🎯 核心特点
public class Connection {private String url;private Connection(String url) {this.url = url;}// 静态工厂方法public static Connection create(String url) {validateUrl(url); // 添加验证逻辑return new Connection(url);}// 有名称的工厂方法public static Connection createSecureConnection() {return new Connection("https://secure.example.com");}
}// 使用
Connection conn = Connection.create("https://api.example.com");
✅ 优点
- 有意义的名称:方法名可以描述创建逻辑
- 控制实例化:可以缓存实例、参数验证、返回子类
- 降低耦合:客户端只需知道工厂方法接口
- 灵活性:可以返回接口而非具体实现
❌ 缺点
- 无法继承:如果类没有公共构造器,则无法被继承
- 不易发现:工厂方法与其他静态方法混在一起
- 需要文档:需要说明哪些是工厂方法
🎯 适用场景
- 需要控制创建逻辑(验证、缓存)
- 创建过程有名称区分不同行为
- 返回接口而非具体实现
- 需要缓存或重用实例
🔍 Android 示例
// Intent 工厂方法
Intent chooserIntent = Intent.createChooser(shareIntent, "Share via");// Bitmap 工厂方法
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);// Uri 解析
Uri uri = Uri.parse("content://com.example.provider/data");
3. 建造者模式 (Builder Pattern)
📖 名词解释
通过一个建造者类来分步构建复杂对象,特别适合参数多的场景。
🎯 核心特点
public class AlertDialogConfig {private final String title;private final String message;private final boolean cancelable;private AlertDialogConfig(Builder builder) {this.title = builder.title;this.message = builder.message;this.cancelable = builder.cancelable;}public static class Builder {private String title;private String message;private boolean cancelable = true;public Builder setTitle(String title) {this.title = title;return this;}public Builder setMessage(String message) {this.message = message;return this;}public Builder setCancelable(boolean cancelable) {this.cancelable = cancelable;return this;}public AlertDialogConfig build() {return new AlertDialogConfig(this);}}
}// 使用
AlertDialogConfig config = new AlertDialogConfig.Builder().setTitle("Warning").setMessage("Are you sure?").setCancelable(false).build();
✅ 优点
- 极佳的可读性:链式调用清晰表达意图
- 参数灵活性:处理多个可选参数
- 不可变对象:适合创建不可变对象
- 参数验证:在build()方法中集中验证
- 分步构建:可以分多个步骤构建
❌ 缺点
- 代码冗余:需要编写大量的样板代码
- 创建开销:需要先创建Builder对象
- 学习成本:对新手可能不太直观
🎯 适用场景
- 具有多个可选参数的对象(4个或更多)
- 需要创建不可变对象
- 参数配置复杂且需要良好可读性
- 需要分步骤构建的复杂对象
🔍 Android 示例
// Notification 建造者
Notification notification = new NotificationCompat.Builder(context, "channel_id").setContentTitle("Title").setContentText("Message").setSmallIcon(R.drawable.ic_notification).build();// Retrofit 建造者
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create()).build();
4. 单例模式 (Singleton Pattern)
📖 名词解释
确保一个类只有一个实例,并提供全局访问点。
🎯 核心特点
// 双重检查锁实现
public class AppManager {private static volatile AppManager instance;private final Context appContext;private AppManager(Context context) {this.appContext = context.getApplicationContext();}public static AppManager getInstance(Context context) {if (instance == null) {synchronized (AppManager.class) {if (instance == null) {instance = new AppManager(context);}}}return instance;}
}// 静态内部类实现(推荐)
public class DatabaseHelper {private DatabaseHelper() {}private static class Holder {static final DatabaseHelper INSTANCE = new DatabaseHelper();}public static DatabaseHelper getInstance() {return Holder.INSTANCE;}
}
✅ 优点
- 全局唯一访问点:确保整个应用中使用同一个实例
- 节省资源:避免重复创建昂贵对象
- 延迟初始化:支持按需创建
- 全局状态管理:方便管理应用级状态
❌ 缺点
- 全局状态:可能导致隐藏的耦合
- 线程安全问题:需要小心处理多线程环境
- 测试困难:全局状态使得单元测试复杂
- 内存泄漏风险:可能持有Context导致内存泄漏
🎯 适用场景
- 全局配置管理
- 资源密集型对象(数据库连接、网络客户端)
- 需要严格单例的系统服务
- 应用级别的状态管理
🔍 Android 示例
// Application 类本身就是单例
public class MyApp extends Application {private static MyApp instance;@Overridepublic void onCreate() {super.onCreate();instance = this;}public static MyApp getInstance() {return instance;}
}// 使用单例
ImageLoader.getInstance().loadImage(url, imageView);
5. 依赖注入 (Dependency Injection)
📖 名词解释
对象的依赖由外部容器提供,而不是自己创建,实现控制反转。
🎯 核心特点
// 手动依赖注入
public class UserRepository {private final ApiService apiService;public UserRepository(ApiService apiService) {this.apiService = apiService; // 依赖注入}
}// 使用 Dagger/Hilt
@Module
@InstallIn(SingletonComponent.class)
public class NetworkModule {@Provides@Singletonpublic Retrofit provideRetrofit() {return new Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create()).build();}
}@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {@InjectRetrofit retrofit; // 自动注入
}
✅ 优点
- 极致解耦:组件间不直接依赖
- 易于测试:可以轻松注入Mock对象
- 生命周期管理:框架管理对象的创建和销毁
- 代码复用:依赖项可在多处共享
- 配置集中化:依赖配置集中在模块中
❌ 缺点
- 学习曲线陡峭:需要理解复杂的概念
- 编译时开销:注解处理增加编译时间
- 调试困难:错误信息可能不直观
- 过度工程:小项目可能过于复杂
🎯 适用场景
- 中大型项目,需要良好的架构
- 需要高度可测试性的项目
- 复杂的依赖关系图
- 团队协作开发,需要统一架构
🔍 Android 示例
// Hilt 注入 ViewModel
@HiltViewModel
public class MainViewModel extends ViewModel {private final UserRepository repository;@Injectpublic MainViewModel(UserRepository repository) {this.repository = repository;}
}// Activity 中使用
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {@InjectMainViewModel viewModel;
}
6. 抽象工厂模式 (Abstract Factory Pattern)
📖 名词解释
创建相关或依赖对象的家族,而不需要指定具体类。
🎯 核心特点
public interface ThemeFactory {Button createButton();TextView createTextView();Dialog createDialog();
}public class LightThemeFactory implements ThemeFactory {@Overridepublic Button createButton() {Button button = new Button(context);button.setBackgroundColor(Color.WHITE);return button;}// 其他方法...
}public class DarkThemeFactory implements ThemeFactory {@Overridepublic Button createButton() {Button button = new Button(context);button.setBackgroundColor(Color.BLACK);return button;}// 其他方法...
}
✅ 优点
- 产品族一致性:确保创建的对象相互兼容
- 开闭原则:易于添加新的产品族
- 客户端解耦:客户端与具体实现解耦
- 统一接口:提供统一的创建接口
❌ 缺点
- 复杂度高:需要定义大量接口和类
- 难以扩展:添加新产品需要修改工厂接口
- 过度设计:简单场景下显得过于复杂
🎯 适用场景
- 需要创建相关或依赖的对象家族
- 系统需要独立于产品的创建、组合和表示
- 需要提供多个产品族,但只使用其中一族
- GUI 主题系统、跨平台UI组件
7. 原型模式 (Prototype Pattern)
📖 名词解释
通过克隆现有对象来创建新实例,避免昂贵的初始化过程。
🎯 核心特点
public class UserProfile implements Cloneable {private String username;private Map<String, Object> preferences;public UserProfile(String username) {this.username = username;this.preferences = loadPreferences(); // 耗时操作}@Overridepublic UserProfile clone() {try {UserProfile cloned = (UserProfile) super.clone();cloned.preferences = new HashMap<>(this.preferences); // 深拷贝return cloned;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}// 使用
UserProfile original = new UserProfile("user123");
UserProfile copy = original.clone(); // 比 new 快很多
✅ 优点
- 性能优化:避免昂贵的初始化过程
- 简化创建:简化复杂对象的创建过程
- 动态配置:可以在运行时克隆配置好的对象
❌ 缺点
- 深拷贝复杂:需要小心处理所有引用类型
- 克隆方法滥用:可能被用于规避构造器逻辑
- 内存占用:可能占用更多内存
🎯 适用场景
- 创建对象成本很高(需要大量计算或IO)
- 需要创建相似但略有不同的对象
- 系统需要独立于如何创建、组合产品
- 游戏开发中的对象池
8. 反射创建 (Reflection)
📖 名词解释
在运行时动态创建对象实例,通过类名等信息来实例化对象。
🎯 核心特点
public class ObjectFactory {public static <T> T createInstance(String className) {try {Class<?> clazz = Class.forName(className);return (T) clazz.newInstance();} catch (Exception e) {throw new RuntimeException("创建实例失败", e);}}
}// 使用
String className = "com.example.MyClass";
MyClass obj = ObjectFactory.createInstance(className);
✅ 优点
- 极度灵活:可以在运行时动态创建任何类的实例
- 实现插件系统:可以加载并实例化未知的类
- 解耦:客户端不需要知道具体类名
❌ 缺点
- 性能差:比直接调用构造器慢很多
- 安全性问题:可以绕过访问控制
- 编译时检查缺失:错误只能在运行时发现
- 代码可读性差:难以理解和维护
🎯 适用场景
- 框架开发(如依赖注入容器)
- 动态加载类(插件系统)
- 序列化/反序列化库
- 配置驱动的对象创建
📊 总结对比表
模式 | 优点 | 缺点 | 适用场景 | 使用频率 |
---|---|---|---|---|
new 关键字 | 简单、高性能、明确 | 紧耦合、缺乏灵活性 | 简单对象、内部使用 | ⭐⭐⭐⭐⭐ |
静态工厂 | 有名称、可控制、可缓存 | 不能继承、不易发现 | 需要控制创建逻辑 | ⭐⭐⭐⭐ |
建造者 | 参数灵活、可读性好 | 代码冗余、创建开销 | 多参数对象、配置复杂 | ⭐⭐⭐ |
单例 | 全局唯一、节省资源 | 全局状态、测试困难 | 全局管理、资源密集型 | ⭐⭐⭐⭐ |
依赖注入 | 解耦、易测试、生命周期管理 | 学习曲线陡、调试复杂 | 中大型项目、需要架构 | ⭐⭐⭐⭐ |
抽象工厂 | 产品族一致性、开闭原则 | 复杂度高、难以扩展 | 创建相关对象家族 | ⭐⭐ |
原型 | 性能优化、避免昂贵初始化 | 深拷贝复杂、可能滥用 | 创建成本高的相似对象 | ⭐ |
反射 | 极度灵活、动态创建 | 性能差、安全问题 | 框架开发、插件系统 | ⭐ |
🎯 Android 开发建议
- 简单场景:优先使用
new
和静态工厂方法 - UI 组件:使用建造者模式(AlertDialog、Notification)
- 业务逻辑:使用依赖注入(Dagger/Hilt)
- 全局服务:谨慎使用单例模式,注意内存泄漏
- 性能敏感:考虑原型模式避免重复昂贵操作
- 框架开发:在必要时使用反射和抽象工厂