設計模式-建立型

設計模式-建立型

目的:實例化過程的解耦java

寫在前面

​ 發現對於落地這件事情仍是要靜下心一個一個目標完成,設計模式一直擱淺了很久也沒個系統整理,做爲網上標配開篇,最近仍是補上這個做業吧spring

  1. 爲何用設計模式數據庫

    • 設計模式是前人總結下來的經驗,對於擴展性和可維護性有很大幫助
    • 也是爲了使設計變得簡單,容易閱讀
  2. 設計模式原則(SOLID)設計模式

    • 單一職責原則(Single Responsibility Principle):能夠理解爲最好一個類只負責一項職責
    • 開閉原則(Open Close Priciple):儘可能對擴展開放,對修改關閉
    • 里氏替換原則(Liskov Substitution Principle):引用父類處能夠用任意子類代替
    • 接口隔離原則(Interface Segregation priciple):創建單一接口,最好是一個類依賴一個接口,而不是多個類依賴一個接口
    • 依賴倒置原則 (Dependency InVersion Principle) :調用方和實現方都應該依賴抽象,彼此相互獨立,實現類應該依賴抽象,而不能反過來
    • 迪米特法則(Law of Demeter):一個對象保持對其餘對象最少的瞭解
    • 合成複用原則(Composite/Aggregate Reuse Principle):儘可能使用組合/聚合,不要使用繼承,繼承基類會暴露實現破壞封裝;基類改變,子類實現也須要改變;實現是靜態的,不夠靈活
  3. 如何使用設計模式

    以上原則只是設計參考的一個約束,並不絕對,對於「最好的設計模式就是不用設計模式」,咱們尚未達到這個境界,只有合適的場景用更合適的方法。緩存

咱們原先想獲取一個新對象ide

Object o = new Object();

以後在建立新對象的場景能夠參考考慮一下使用如下的思路工具

  1. 單例模式

    說明:一個類只能有一個實例,提供全局惟一的訪問點優化

    應用場景:控制資源場景,例如數據庫鏈接池,線程池等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 對於循環依賴的解決方案

  2. 簡單工廠

    說明:根據傳入的變量決定輸出什麼樣的實例

    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;
            }
        }
    }
  3. 工廠方法

    說明:建立對象行爲進行抽象,在子類裏實現邏輯

    適用場景:

    • 以下是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();
          }
      }
  4. 抽象工廠

    說明:建立相關或依賴對象的家族,而無需明確指定具體類

    適用場景:對象的建立和使用隔離開來

    • Collection類中抽象了多個工廠方法,自己又是一個抽象的建立類
  5. 建造者模式

    說明:封裝一個對象複雜的構建過程

    適用場景:crud時候,優化繁瑣的實體構建過程

    • lombok @Builder

      Builder builder = Builder
                         .age(10)
                          .name("builder")
                          .build();
  6. 原型模式

    說明:實例對象的複製獲取新實例

    //淺拷貝,僅對象內的引用也被複制時爲深拷貝
    @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;
        }
    }
  7. 總結

    以上是對建立型的設計模式的一些demo及一些源碼的引用,目的是儘快的理解和快速的用起來,後續會補全UML圖

    其中最經常使用的是單例模式/工廠方法/抽象工廠/建造者模式,設計模式的主要目的也是爲了代碼的可維護性和可擴展性,把會變更的地方和不變的地方隔離開來

若有不正確的地方歡迎大佬指正

本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈
相關文章
相關標籤/搜索