設計模式
單例模式-singleton
- Spring的Bean工廠就是單例模式,項目中自己寫的情況越來越少
工程中最常用版本-餓漢式
/**
* 優點:線程安全
* 缺點:不管用到與否,類裝載時就完成實例化
*/
public class Singleton_01 {
private static final Singleton_01 INSTANCE = new Singleton_01();
private Singleton_01() {};
public static Singleton_01 getInstance() {
return INSTANCE;
}
public static void main(String[] args) {
Singleton_01 m1 = Singleton_01.getInstance();
Singleton_01 m2 = Singleton_01.getInstance();
System.out.println(m1 == m2);
}
}
雙重鎖檢查-懶漢式
/**
* 完美版本
* 缺點:加鎖帶來效率下降
* 優點:volatile禁止指令重排序,防止半初始化現象。
* 優點:雙重檢查保證鎖的粒度更小,且消除重複new對象的問題
*/
public class Singleton_02 {
private static volatile Singleton_02 INSTANCE; //JIT
private Singleton_02() {
}
public static Singleton_02 getInstance() {
if (INSTANCE == null) {
synchronized (Singleton_02.class) {
// 第二次檢查如果其他線程完成了初始化,其他線程無法進入
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton_02();
}
}
}
return INSTANCE;
}
}
完美版本,但不直觀
package com.mashibing.dp.singleton;
/**
* 不僅可以解決線程同步,還可以防止反序列化。
*/
public enum Singleton_03 {
INSTANCE;
public static void main(String[] args) {
for(int i=0; i<100; i++) {
new Thread(()->{
System.out.println(Singleton_03.INSTANCE.hashCode());
}).start();
}
}
}
策略模式-Strategy
- Java的Comparator接口,該接口只有一個抽象方法compare(T o1, T o2)就是策略模式的一個應用;
修改關閉,擴展開放
- 實現排序方法,自己實現比較器傳入,就是不同的策略傳入,實現可擴展性,策略模式是封裝的做一件事的不同的方式
Java的Comparator接口策略分析
- 策略:這裏是比較策略,類比其他的比如售賣策略等
public interface Comparator<T> {
int compare(T o1, T o2);
}
- 具體策略實現:這裏定義根據對象的id來比較。類比售貨打八折銷售,滿減等策略
Comparator<User> comparator = new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId() - o2.getId();
}
};
- 應用策略:事先定義好策略應用
// 比如list的sort方法,需要傳入比較策略
public static void main(String[] args) {
List<User> l = new ArrayList<>();
l.add(new User(2, "zhangsan", "123", "aaaa"));
l.add(new User(3, "zhangsan", "123", "aaaa"));
l.add(new User(1, "zhangsan", "123", "aaaa"));
Comparator<User> comparator = new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId()-o2.getId();
}
};
l.sort(comparator);
}
// list的sort方法對比較策略的應用,事實上是用泛型接收具體類型
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
- 策略模式的實質是把具體的實現策略抽離出來,達到可擴展的目的,比如要進行比較,那麼比較策略我們自己指定,“比較”動作可以識別我們傳入的策略,和多態有點相似