设计模式
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式分为三大类(23种):
- 创建模型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
- 结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
- 行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
单例模式
单例模式(singleton):某个类只能生成一个实例,该类提供了一个全局访问点(一个公共方法)供外部获取该实例。
优点:
只有一个实例,节约内存资源,提高系统性能。
某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
缺点:
在登录场景下使用单例模式是很常见的,因为登录状态通常是全局的,需要在应用程序的多个地方进行访问。通过单例模式,可以确保在整个应用程序生命周期内只有一个登录实例存在,从而避免了多次登录或者状态不一致的情况
饿汉式
package com.heroxin.singleton;
import java.io.Serializable;
public class Singleton01 implements Serializable { private Singleton01() { if (INSTANCE != null) { throw new RuntimeException("单例对象不能重复创建"); } System.out.println("private Singleton01():饿汉式"); }
private static final Singleton01 INSTANCE = new Singleton01();
public static Singleton01 getInstance() { return INSTANCE; }
public static void otherMethod() { System.out.println("otherMethod()"); }
public Object readResolve() { return INSTANCE; } }
|
package com.heroxin.singleton;
import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class TestSingleton01 { public static void main(String[] args) throws Exception { Singleton01.otherMethod(); System.out.println("==============="); System.out.println(Singleton01.getInstance()); System.out.println(Singleton01.getInstance());
}
private static void serializable(Object instance) throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(instance); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); System.out.println("反序列化创建实例:" + ois.readObject()); }
private static void reflection(Class<?> clazz) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { for (Constructor<?> constructor : clazz.getDeclaredConstructors()) { System.out.println(constructor); } Constructor<?> constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); System.out.println("反射创建实例:" + constructor.newInstance()); } }
|
饿汉式 — 枚举
package com.heroxin.singleton;
public enum Singleton02 { INSTANCE;
Singleton02() { System.out.println("private Singleton02():饿汉式 --- m"); }
public static Singleton02 getInstance() { return INSTANCE; }
public static void otherMethod() { System.out.println("otherMethod()"); }
@Override public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } }
|
package com.heroxin.singleton;
import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class TestSingleton02 { public static void main(String[] args) throws Exception { Singleton02.otherMethod(); System.out.println("==============="); System.out.println(Singleton02.getInstance()); System.out.println(Singleton02.getInstance()); }
}
|
懒汉式
package com.heroxin.singleton;
import java.io.Serializable;
public class Singleton03 implements Serializable { private Singleton03() {
System.out.println("private Singleton03():懒汉式"); }
private static Singleton03 INSTANCE = null;
public static synchronized Singleton03 getInstance() {
if (INSTANCE == null) { INSTANCE = new Singleton03(); } return INSTANCE; }
public static void otherMethod() { System.out.println("otherMethod()"); }
}
|
package com.heroxin.singleton;
import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class TestSingleton03 { public static void main(String[] args) throws Exception { Singleton03.otherMethod(); System.out.println("==============="); System.out.println(Singleton03.getInstance()); System.out.println(Singleton03.getInstance()); }
}
|
懒汉式 — DCL
package com.heroxin.singleton;
import java.io.Serializable;
public class Singleton04 implements Serializable { private Singleton04() {
System.out.println("private Singleton04():懒汉式 -- DCL"); }
private static volatile Singleton04 INSTANCE = null;
public static Singleton04 getInstance() { if (INSTANCE == null) { synchronized (Singleton04.class) { if (INSTANCE == null) { INSTANCE = new Singleton04(); } } } return INSTANCE; }
public static void otherMethod() { System.out.println("otherMethod()"); }
}
|
package com.heroxin.singleton;
import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class TestSingleton04 { public static void main(String[] args) throws Exception { Singleton04.otherMethod(); System.out.println("==============="); System.out.println(Singleton04.getInstance()); System.out.println(Singleton04.getInstance()); }
}
|
懒汉式 — 内部类
package com.heroxin.singleton;
import java.io.Serializable;
public class Singleton05 implements Serializable { private Singleton05() { System.out.println("private Singleton05():懒汉式 -- 内部类"); }
private static class Holder{ static Singleton05 INSTANCE = new Singleton05(); };
public static Singleton05 getInstance() { return Holder.INSTANCE; }
public static void otherMethod() { System.out.println("otherMethod()"); }
}
|
package com.heroxin.singleton;
import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class TestSingleton05 { public static void main(String[] args) throws Exception { Singleton05.otherMethod(); System.out.println("==============="); System.out.println(Singleton05.getInstance()); System.out.println(Singleton05.getInstance()); } }
|
参考文章:
Java中常用的设计模式
单例模式