创建型模式提供创建对象的机制, 能够提升已有代码的灵活性和可复⽤性。
类型 | 实现要点 |
---|---|
工厂方法 | 定义⼀个创建对象的接⼝,让其⼦类⾃⼰决定实例化哪⼀个⼯⼚类,⼯⼚模式使其创建过程延迟到⼦类进⾏。 |
抽象工厂 | 提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。 |
建造者 | 将⼀个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示 |
原型 | ⽤原型实例指定创建对象的种类,并且通过拷⻉这些原型创建新的对象。 |
单例 | 保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。 |
在设计模式中按照不同的处理⽅式共包含三⼤类:
其中创建型模式⽬前已经搞了其中的四个:
单例模式可以说是整个设计中最简单的模式之⼀,在编程开发中经常会遇到这样⼀种场景,那就是需要保证⼀个类只有⼀个实例哪怕多线程同时访问,并需要提供⼀个全局访问此实例的点。
单例模式主要解决的是,⼀个全局使⽤的类频繁的创建和消费,从⽽提升提升整体的代码的性能。
⽇常开发所能⻅到的,例如:
在我们的⽇常开发中⼤致上会出现如上这些场景中使⽤到单例模式,虽然单例模式并不复杂但是使⽤⾯却⽐较⼴。
设计模式 - 创建型模式_ 单例模式 Singleton Pattern
单例模式的实现⽅式⽐较多,主要在实现上是否⽀持懒汉模式、是否线程安全中运⽤各项技巧。
当然也有⼀些场景不需要考虑懒加载也就是懒汉模式的情况,会直接使⽤ static 静态类或属性和⽅法的⽅式进⾏处理,供外部调⽤。
那么接下来我们就通过实现不同⽅式的实现单例模式。
public class Singleton_00 {
public static Map<String,String> cache = new ConcurrentHashMap<String, String>();
}
public class Singleton_01 {
private static Singleton_01 instance;
private Singleton_01() {
}
public static Singleton_01 getInstance(){
if (null != instance) return instance;
return new Singleton_01();
}
}
public class Singleton_02 {
private static Singleton_02 instance;
private Singleton_02() {
}
public static synchronized Singleton_02 getInstance(){
if (null != instance) return instance;
return new Singleton_02();
}
}
此种模式虽然是安全的,但由于把锁加到⽅法上后,所有的访问都因需要锁占⽤导致资源的浪费。 如果不是特殊情况下,不建议此种⽅式实现单例模式。
public class Singleton_03 {
private static Singleton_03 instance = new Singleton_03();
private Singleton_03() {
}
public static Singleton_03 getInstance() {
return instance;
}
}
public class Singleton_04 {
private static class SingletonHolder {
private static Singleton_04 instance = new Singleton_04();
}
private Singleton_04() {
}
public static Singleton_04 getInstance() {
return SingletonHolder.instance;
}
}
public class Singleton_05 {
private static Singleton_05 instance;
private Singleton_05() {
}
public static Singleton_05 getInstance(){
if(null != instance) return instance;
synchronized (Singleton_05.class){
if (null == instance){
instance = new Singleton_05();
}
}
return instance;
}
}
import java.util.concurrent.atomic.AtomicReference;
public class Singleton_06 {
private static final AtomicReference<Singleton_06> INSTANCE = new AtomicReference<Singleton_06>();
private static Singleton_06 instance;
private Singleton_06() {
}
public static final Singleton_06 getInstance() {
for (; ; ) {
Singleton_06 instance = INSTANCE.get();
if (null != instance) return instance;
INSTANCE.compareAndSet(null, new Singleton_06());
return INSTANCE.get();
}
}
public static void main(String[] args) {
System.out.println(Singleton_06.getInstance());
System.out.println(Singleton_06.getInstance());
}
}
AtomicInteger 、 AtomicBoolean 、 AtomicLong 、 AtomicReference
。public enum Singleton_07 {
INSTANCE;
public void test(){
System.out.println("hi~");
}
}
约书亚·布洛克(英语:Joshua J. Bloch,1961年8⽉28⽇-),美国著名程序员。他为Java平台设计并实作了许多的功能,曾担任Google的⾸席Java架构师(Chief Java Architect)。
调⽤⽅式:
@Test
public void test() {
Singleton_07.INSTANCE.test();
}
这里我们看到了懒汉、饿汉、线程是否安全、静态类、内部类、加锁、串⾏化等等各种技能。
在平时的开发中如果可以确保此类是全局可⽤不需要做懒加载,那么直接创建并给外部调⽤即可。
但如果是很多的类,有些需要在⽤户触发⼀定的条件后才显示,那么⼀定要⽤懒加载。线程的安全上可以按需选择。