Android/Java中创建类实例的各种模式实例代码
作者:沪cares
这篇文章主要介绍了Android/Java中创建类实例各种模式的相关资料,包括New关键字、静态工厂方法、建造者模式、单例模式、依赖注入、抽象工厂模式、原型模式和Reflection,每个模式有其特点和适用场景,需要的朋友可以参考下
创建型模式总览
模式名称 | 核心思想 | 使用频率 | 难度 |
---|---|---|---|
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; @Override public 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 @Singleton public Retrofit provideRetrofit() { return new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); } } @AndroidEntryPoint public class MainActivity extends AppCompatActivity { @Inject Retrofit retrofit; // 自动注入 }
优点
- 极致解耦:组件间不直接依赖
- 易于测试:可以轻松注入Mock对象
- 生命周期管理:框架管理对象的创建和销毁
- 代码复用:依赖项可在多处共享
- 配置集中化:依赖配置集中在模块中
缺点
- 学习曲线陡峭:需要理解复杂的概念
- 编译时开销:注解处理增加编译时间
- 调试困难:错误信息可能不直观
- 过度工程:小项目可能过于复杂
适用场景
- 中大型项目,需要良好的架构
- 需要高度可测试性的项目
- 复杂的依赖关系图
- 团队协作开发,需要统一架构
Android 示例
// Hilt 注入 ViewModel @HiltViewModel public class MainViewModel extends ViewModel { private final UserRepository repository; @Inject public MainViewModel(UserRepository repository) { this.repository = repository; } } // Activity 中使用 @AndroidEntryPoint public class MainActivity extends AppCompatActivity { @Inject MainViewModel viewModel; }
6. 抽象工厂模式 (Abstract Factory Pattern)
名词解释
创建相关或依赖对象的家族,而不需要指定具体类。
核心特点
public interface ThemeFactory { Button createButton(); TextView createTextView(); Dialog createDialog(); } public class LightThemeFactory implements ThemeFactory { @Override public Button createButton() { Button button = new Button(context); button.setBackgroundColor(Color.WHITE); return button; } // 其他方法... } public class DarkThemeFactory implements ThemeFactory { @Override public 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(); // 耗时操作 } @Override public 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)
- 全局服务:谨慎使用单例模式,注意内存泄漏
- 性能敏感:考虑原型模式避免重复昂贵操作
- 框架开发:在必要时使用反射和抽象工厂
到此这篇关于Android/Java中创建类实例的各种模式的文章就介绍到这了,更多相关Java创建类实例模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!