目的:實例化過程的解耦java
發現對於落地這件事情仍是要靜下心一個一個目標完成,設計模式一直擱淺了很久也沒個系統整理,做爲網上標配開篇,最近仍是補上這個做業吧spring
爲何用設計模式數據庫
設計模式原則(SOLID)設計模式
以上原則只是設計參考的一個約束,並不絕對,對於「最好的設計模式就是不用設計模式」,咱們尚未達到這個境界,只有合適的場景用更合適的方法。緩存
咱們原先想獲取一個新對象ide
Object o = new Object();
以後在建立新對象的場景能夠參考考慮一下使用如下的思路工具
說明:一個類只能有一個實例,提供全局惟一的訪問點優化
應用場景:控制資源場景,例如數據庫鏈接池,線程池等ui
匿名內部類this
class SingletonInnerClass { // 私有構造器保證不能new 建立新實例 private SingletonInnerClass() { } public static SingletonInnerClass getInstance() { return SingletonInner.instance; } private static class SingletonInner { private static final SingletonInnerClass instance = new SingletonInnerClass(); } }
枚舉類型
enum SingletonEnum { INSTACN; }
雙重檢查鎖
class SingletonDCL { private volatile static SingletonDCL instance; private SingletonDCL() { } public static SingletonDCL getInstance() { if (instance == null) { synchronized (SingletonDCL.class) { if (instance == null) { instance = new SingletonDCL(); } } } return instance; } }
Spring單例註冊表
/** Cache of singleton objects: bean name to bean instance. */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** Cache of singleton factories: bean name to ObjectFactory. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** Cache of early singleton objects: bean name to bean instance. 提早曝光的單例Cache */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 一級緩存 獲取單例的bean Object singletonObject = this.singletonObjects.get(beanName); // 判斷bean是否在建立中(並未建立完) if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 二級緩存 獲取提早曝光的單例 singletonObject = this.earlySingletonObjects.get(beanName); // 判斷是否容許提早引用 if (singletonObject == null && allowEarlyReference) { // 三級緩存 獲取單例bean ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 放入二級緩存 並刪除三級緩存中的bean singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
上面也直接說了spring 對於循環依賴的解決方案
說明:根據傳入的變量決定輸出什麼樣的實例
interface Product { void use(); } // 產品實現 class ProductA implements Product { @Override public void use() { System.out.println("product A"); } } class ProductB implements Product { @Override public void use() { System.out.println("product B"); } } // 工廠 class Factory { public Product produce(String type) { if ("A".equals(type)) { return new ProductA(); } else if ("B".equals(type)) { return new ProductB(); } else { return null; } } }
說明:建立對象行爲進行抽象,在子類裏實現邏輯
適用場景:
以下是spring中的工廠方法接口
public interface FactoryBean<T> { @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } }
jdk中Collection類
public interface Collection<E> extends Iterable<E> { ... // 這是一個工廠方法 Iterator<E> iterator(); ... } // 實如今子類中 public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { public Iterator<E> iterator() { return new Itr(); } }
說明:建立相關或依賴對象的家族,而無需明確指定具體類
適用場景:對象的建立和使用隔離開來
說明:封裝一個對象複雜的構建過程
適用場景:crud時候,優化繁瑣的實體構建過程
lombok @Builder
Builder builder = Builder .age(10) .name("builder") .build();
說明:實例對象的複製獲取新實例
//淺拷貝,僅對象內的引用也被複制時爲深拷貝 @Data @AllArgsConstructor class Prototype implements Cloneable { private String name; private Map<String, String> map; @Override public Prototype clone() throws CloneNotSupportedException { Prototype prototype = (Prototype) super.clone(); prototype.map = map; prototype.name = name; return prototype; } }
以上是對建立型的設計模式的一些demo及一些源碼的引用,目的是儘快的理解和快速的用起來,後續會補全UML圖
其中最經常使用的是單例模式/工廠方法/抽象工廠/建造者模式,設計模式的主要目的也是爲了代碼的可維護性和可擴展性,把會變更的地方和不變的地方隔離開來
若有不正確的地方歡迎大佬指正
本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈