时间:2025-05-13 15:26
人气:
作者:admin
《Head First设计模式》读书笔记
相关代码:Vks-Feng/HeadFirstDesignPatternNotes: Head First设计模式读书笔记及相关代码
用来创建独一无二的,只能有一个实例的对象的入场券
有些对象只能有一个实例
为什么不去靠人为约定或全局变量实现该目标?
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() { }
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
为什么会被这样设计?
new,为了避免被多次创建,将类的构造器私有化。
延迟实例化(Lazy instantiate)
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
当我们需要该实例时再去创建对象,如果不需要就永远不会产生。
HeadFirst设计模式6-单件模式
单件模式确保一个类只有一个实例,并提供一个全局访问点。

某公司设计的巧克力锅炉控制器
需要避免糟糕的情况发生:排除未煮沸的原料、已满情况下继续加原料、未放原料就空烧
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
public ChocolateBoiler() {
empty = true;
boiled = false;
}
public void fill() {
if (isEmpty()) {
empty = false;
boiled = false;
// 填充原料
}
} public void drain() {
if (isEmpty() && isBoiled()) {
empty = true;
}
} public void boil() {
if (!isEmpty() && !isBoiled()) {
boiled = true;
}
}
private boolean isBoiled() {
return boiled;
}
private boolean isEmpty() {
return empty;
}
}
为了避免同时存在多个实例带来问题,对其进行单件化改造
public class ChocolateBoiler {
private static ChocolateBoiler uniqueInstance;
private boolean empty;
private boolean boiled;
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new ChocolateBoiler();
}
return uniqueInstance;
}
private ChocolateBoiler() {
empty = true;
boiled = false;
}
}
当有多个熔炉实例时,可能会发生我们先前想避免的问题,但上面已有的单例模式可能会在多线程情况下创建出不只一个实例。
只要把getInstance()变成同步(synchronized)方法,多线程灾难几乎就可以轻易地解决了
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
问题:同步会降低性能,且当实例被正确初始化后,后续就不用再同步了,同步将会彻底成为累赘
getInstance()的性能对应用程序不是很关键,就什么都别做
getInstance()被频繁使用时,就需要考虑优化了getInstance()时可用public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() { }
public static synchronized Singleton getInstance() {
return uniqueInstance;
}
}
getInstance()中减少使用同步
private volatile static Singleton uniqueInstance;
private Singleton() { }
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
volatile关键字确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量Q:为何不创建一个类,将其所有方法和变量都定义为静态的,直接把类当作一个单件?
A:
Q:类加载器(class loader),听说两个类加载器可能有机会创建自己的单件实例
A:是的
Q:可不可以继承单件类?
A:继承单间类面临的问题:构造器是私有的。不能用私有构造器来扩展类。所以你必须把单件的构造器改成公开的或受保护的,而这样:
Q:为什么全局变量比单件模式差?
A:
OO基础
OO原则
OO模式
要点:
下一篇:JWT令牌