當前位置: 妍妍網 > 碼農

Spring 都用到哪些設計模式?99% 的人答不全!

2024-05-29碼農

引言:設計模式是我們計畫中經常會涉及到的計畫進行重構、解構時的一種方法,像常見的單例模式、工廠模式、策略模式、裝飾器模式都是比較常用的,關於 23 種設計模式,大家可以找本書專門去翻看一下,在 Java 框架的源碼中也不例外,設計模式的使用實在是太多了,本文就來分析 Spring 中用到的設計模式。

題目

你了解的 Spring 都用到哪些設計模式?

推薦解析

工廠設計模式

優點

1) 封裝物件建立過程 :工廠模式將物件的建立過程封裝在工廠類中,客戶端程式碼無需關心具體的建立細節,只需透過工廠類獲取所需物件的例項,從而簡化了物件的例項化過程。

2) 解耦合 :客戶端程式碼與具體產品類解耦,減少了程式碼的依賴性,提高了程式碼的靈活性和可維護性。如果需要更換產品類,只需修改工廠類即可,而不必修改客戶端程式碼。

3) 復用性 :由於物件的建立邏輯集中在工廠類中,可以在多個地方重復使用,避免了重復的建立程式碼,提高了程式碼的復用性。

4) 單一職責原則 :工廠類專門負責物件的建立,遵循了單一職責原則,每個類都專註於自己的任務,程式碼結構清晰。

5) 更好的擴充套件性 :如果需要添加新的產品類,只需擴充套件工廠類即可,符合開閉原則,系統擴充套件性較好。

缺點

1) 類數量增加 :引入了工廠類之後,類的數量將會增加,增加了系統的抽象性和理解難度。

2) 增加了系統復雜度 :雖然工廠模式能夠將物件的建立過程封裝起來,但也引入了額外的復雜度和間接性,不適合建立簡單的物件。

3) 不易於理解 :對於初學者來說,理解工廠模式可能會增加一定的學習成本,需要理解工廠類、抽象產品類等概念。

使用場景

  • 當一個類不知道它所需要的物件的類時(例如需要根據條件動態建立物件),可以使用工廠模式。

  • 當一個類希望由它的子類別來指定所建立的物件時,可以使用工廠模式。

  • 當類中的某些部份依賴於具體建立物件的時候,可以考慮使用工廠模式。

  • 當系統需要動態地決定建立哪些類的物件時,可以使用工廠模式。

  • Spring 源碼

    在 Spring 中,Bean 的建立通常透過工廠方法模式來實作。即透過一個工廠類(通常是實作了 FactoryBean 介面的類)來建立和管理 Bean 物件。

    publicinterfaceFactoryBean<T{
    getObject()throws Exception;
    class<?> getObjectType();
    booleanisSingleton();
    }

    在 Spring 中,Bean 的建立也可以透過抽象工廠模式來實作。Spring 提供了多種抽象工廠來管理不同型別的 Bean,例如 BeanFactory 和 ApplicationContext。

    publicinterfaceBeanFactory{
    Object getBean(String name)throws BeansException;
    <T> getBean(String name, class<T> requiredType)throws BeansException;
    booleancontainsBean(String name);
    ...
    }

    單例設計模式

    優點

    1) 全域唯一例項 :確保一個類只有一個例項存在,可以節省系統資源,避免頻繁建立和銷毀物件。

    2) 全域存取點 :提供一個全域的存取點來存取唯一例項,方便對例項進行統一的管理和操作。

    3) 延遲例項化 :可以延遲物件的例項化,只有在第一次存取時才會建立例項,提高了系統的效能和資源利用率。

    4) 避免多次例項化 :在多執行緒或分布式環境下,可以避免多次例項化相同的物件,確保物件的唯一性。

    缺點

    1) 可能引起資源浪費 :如果單例物件過早地建立並長時間占用記憶體,可能會引起資源浪費,特別是在物件占用大量資源時。

    2) 不適合動態環境 :單例物件一旦建立之後,其狀態可能會一直保持,不適合需要頻繁改變狀態的場景。

    3) 隱藏依賴關系 :單例模式會隱藏類之間的依賴關系,增加了類之間的耦合度,使得程式碼難以理解和維護。

    使用場景

  • 資源共享 :需要共享某個資源(如資料庫連線池、執行緒池等)的場景,可以使用單例模式確保全域唯一性,避免資源的多次建立和銷毀。

  • 工具類 :某些工具類只需要一個例項來提供全域的功能,例如日誌工具類、配置管理類等。

  • 控制例項數目 :某些類只需要一個例項來控制其例項數目,例如執行緒池、緩存管理器等。

  • 全域狀態配置類 :某些類需要保存全域的配置資訊,例如系統設定類、全域狀態類等。

  • Spring 源碼

    在 Spring 源碼中,最常見的使用單例設計模式的場景就是在建立 Bean 例項時使用單例模式。Spring 容器預設情況下會將所有的 Bean 物件作為單例物件進行管理,這樣可以節省資源,提高效能。

    public classDefaultSingletonBeanRegistryimplementsSingletonBeanRegistry{
    privatefinal Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    @Override
    public Object getSingleton(String beanName){
    returnthis.singletonObjects.get(beanName);
    }
    @Override
    publicvoidregisterSingleton(String beanName, Object singletonObject){
    synchronized (this.singletonObjects) {
    Object oldObject = this.singletonObjects.get(beanName);
    if (oldObject != null) {
    thrownew IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName +
    "': there is already object [" + oldObject + "] bound");
    }
    this.singletonObjects.put(beanName, singletonObject);
    }
    }
    // 其他方法...
    }


    下一期講解 Spring 的代理模式、樣版方法、觀察者模式,可以關註面試鴨公眾號後收到第一時間的推文。

    其他補充

    魚聰明 AI 的回答:

    魚聰明 AI 地址:https://www.yucongming.com/

    Spring 框架在設計和實作過程中廣泛運用了多種設計模式,以下是一些常用的設計模式在 Spring 中的套用:

    1. 單例模式(Singleton Pattern):在 Spring 中,預設情況下 Bean 是單例的,即容器中只會建立一個例項。透過單例模式,Spring 確保了 Bean 在整個應用程式中只會建立一次,節省資源,提高效能。

    2. 工廠模式(Factory Pattern):Spring 中的 BeanFactory 和 ApplicationContext 介面都是工廠模式的典型套用,用於建立和管理 Bean 例項。

    3. 代理模式(Proxy Pattern):Spring AOP(面向切面編程)功能中使用了代理模式,透過代理物件來實作橫切關註點的切面功能。

    4. 觀察者模式(Observer Pattern):Spring 事件機制基於觀察者模式,透過釋出-訂閱的方式實作事件的監聽和處理。

    5. 樣版模式(Template Pattern):Spring 中的 JdbcTemplate 和 RestTemplate 等樣版類都是基於樣版模式實作的,提供了統一的樣版方法供開發者使用。

    6. 策略模式(Strategy Pattern):Spring AOP 中的 Advice 和 Pointcut 就是策略模式的套用,透過不同的策略實作不同的橫切邏輯。

    7. 裝飾者模式(Decorator Pattern):Spring 中的裝飾者模式用於在 Bean 的初始化過程中添加額外的功能,如事務管理、日誌記錄等。

    8. 介面卡模式(Adapter Pattern):Spring MVC 中的 HandlerAdapter 就是介面卡模式的套用,用於適配不同型別的處理器。

    除了上述列舉的設計模式外,Spring 框架還涵蓋了更多設計模式的套用,比如組合模式、樣版方法模式、享元模式等。透過合理運用設計模式,Spring 實作了松耦合、可延伸、易維護的特性,成為一個功能強大、靈活性高的框架。

    歡迎交流

    本文主要講解兩個設計模式,工廠模式和單例模式,可以詳細看下 Spring 的源碼進行分析,在面試時候提及設計模式,可以用源碼進行舉例,是一個不錯的選擇,在文末還有三個問題,歡迎在評論區留言!

    1)Spring 框架中的依賴註入是如何實作的?它與傳統的依賴尋找有什麽區別和優勢?

    2)單例設計模式可以套用在哪些場景?

    3)工廠模式一般可以配合哪些設計模式?

    點燃求職熱情!每周持續更新,海量面試題和大廠面經等你挑戰!趕緊關註面試鴨公眾號,輕松備戰春招和暑期實習!

    往期推薦