05原型与单例模式
原型模式
-
定义:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。
- 备注
- 通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址
- 通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
- 备注
-
简单结构:3个角色
- Prototype(抽象原型类)
- ConcretePrototype(具体原型类)
- Client(客户类)
-
拓展:浅克隆与深克隆
- 浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
- 在代码中使用clone()方法实现浅克隆
- 深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制
- 在代码中使用实现Serializable接口实现深克隆
-
原型管理器:原型管理器(Prototype Manager)将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得
-
优缺点:
- 优点:
- 简化对象的创建过程
- 扩展性较好
- 提供了简化的创建结构
- 可以使用深克隆的方式保存对象的状态
- 缺点:
- 需要为每一个类配备一个克隆方法
- 实现深克隆时需要编写较为复杂的代码
- 优点:
-
适用环境:
- 创建新对象成本较大,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改
- 系统要保存对象的状态,而对象的状态变化很小
- 需要避免使用分层次的工厂类来创建分层次的对象
单例模式
-
定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
-
要点:某个类只能有一个实例;必须自行创建这个实例;必须自行向整个系统提供这个实例
-
简单结构:一个单例角色
1.Singleton(单例)
- 拓展:饿汉式单例与懒汉式单例
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() { }
public static EagerSingleton getInstance() {
return instance;
}
}
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
注意:如果多个线程同时访问将导致创建多个单例对象!怎么办?
双重检查锁
- 锁方法
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() { }
synchronized public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
- 锁代码段
...
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
instance = new LazySingleton();
}
}
return instance;
}
...
- 双重检查锁定
public class LazySingleton {
private volatile static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() {
//第一重判断
if (instance == null) {
//锁定代码块
synchronized (LazySingleton.class) {
//第二重判断
if (instance == null) {
instance = new LazySingleton(); //创建单例实例
}
}
}
return instance;
}
-
区别:
- 饿汉式单例类:无须考虑多个线程同时访问的问题;调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长
- 懒汉式单例类:实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能受到一定影响
-
优缺点:
- 优点:
- 提供了对唯一实例的受控访问
- 可以节约系统资源,提高系统的性能
- 允许可变数目的实例(多例类)
- 缺点:
- 扩展困难(缺少抽象层)
- 单例类的职责过重
- 由于自动垃圾回收机制,可能会导致共享的单例对象的状态丢失
- 优点:
-
适用环境:
- 系统只需要一个实例对象,或者因为资源消耗太大而只允许创建一个对象
- 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律