官术网_书友最值得收藏!

1.2.5 迪米特法則

迪米特法則(Law of Demeter,LOD),又叫作最少知識原則(The Least Knowledge Principle),一個類對于其他類知道得越少越好。簡單來說就是只暴露方法入口,而實現細節不需要暴露給調用者。

干澀的文字描述總是不能給讀者帶來清晰的認知,在本書后續項目落地設計模式實戰的“多種類第三方支付”章節,會為大家帶來“策略模式+門面模式+工廠模式+亨元模式”的落地實戰。調用者只需要關心支付類型(如支付寶支付、微信支付等),無須關心具體的支付交互細節,“門面模式”就是一種遵循迪米特法則的、極具代表性的實現。

關于項目實戰落地,我們后續章節細細道來。在這里,我更想和大家聊聊Spring源碼中哪部分的設計是最具代表性的、最能體現遵循迪米特法則的設計。我們先來回憶一下Spring容器使用的簡單示例,代碼如下:

以上代碼是Spring容器使用最為基礎的示例,相信接觸過Spring框架的讀者對此都了然于心。從代碼的書寫過程中可以看到,想要使用Spring框架,我們僅僅關心以下三點即可。

①XML配置文件的創建或者標有@ComponentScan配置類的創建及注解使用。

②ApplicationContext的構造函數及入參。

③getBean方法的使用。

作為Spring框架的使用者,我們僅僅需要知道以上三點就可以了,可是Spring源碼為我們做了很多。以注解容器AnnotationConfigApplicationContext的創建方式為例(注解方式是趨勢,簡單方便,避免對復雜XML配置文件的維護管理),我們來看一下Spring源碼為我們做了什么,先來看容器創建的入口——AnnotationConfigApplicationContext的構造函數,代碼如下:

構造函數很清晰,包含三行代碼,接下來我們分別對這三行函數所包含的內容進行說明。

(1)this()方法。

this()方法調用了無參構造函數,我們來看看無參構造函數做了些什么,代碼如下:

依然是很清晰的邏輯,表面看無非是創建了兩個對象,但是這兩行代碼實際上為我們做了很多重要的底層邏輯,很抱歉不能夠更深層次地進行源碼的展示,但筆者會盡最大可能為大家解釋這兩行代碼所完成的功能,如果你閱讀過Spring源碼必然會產生共鳴,如果你即將要閱讀Spring源碼必然會有所幫助,當然,你最終也會深刻地體會到Spring的這部分源碼設計是如何遵循迪米特法則的。接下來我們來介紹以下這兩行代碼的功能。

①創建讀取Annotation注解下的BeanDefinition閱讀器,為Bean工廠添加比較器依賴,如@Order注解、@Priority注解,為Bean工廠添加延時加載依賴,如@Lazy注解。

②注冊Spring依賴的BeanDefinition,如內部注解配置處理器internal-ConfigurationAnnotationProcessor、內部依賴注入處理器internalAutowiredAnnotatio nProcessor等。

③初始化Spring運行的Environment,如SystemProperties、systemEnvironment。

④基于“初始化子類之前需提前初始化父類”的規則,隱性地在父類GenericApplicationContext的無參構造中初始化Bean工廠核心類——DefaultListableBeanFactory。

⑤創建classPath的包掃描器,為后續自定義的Bean提供掃描功能。

這些都是我們無須關心的,各種Bean對象的讀取、注冊、掃描,甚至運行環境的初始化我們都無須關心。最小知識原則就體現在這里。

(2)register(componentClasses)方法。

我們先來看看該方法的源碼,代碼如下:

我們可以看到,該方法依靠我們在this()方法中創建的reader進行配置類的注冊,最終會通過我們在“依賴倒置原則”所介紹的registerBeanDefinition方法進行BeanDefinition的注冊,此處就不再過多地展開描述。

(3)refresh()方法。

這個方法是Spring容器初始化的核心,這個方法涉及的內容十分豐富,我們來看看它都做了些什么,代碼如下(方法功能介紹請參見注釋):

試想一下,如果Spring沒有為我們做以上的功能,那么監聽器要自己實現,消息處理器要自己實現,事件分發要自己考慮,這將是非常可怕的事情。Spring僅為使用者暴露了有限的、簡單的方法調用入口,而將其他所有的功能隱藏起來,做到了最少知識原則,符合迪米特法則。

主站蜘蛛池模板: 六安市| 抚远县| 青神县| 清镇市| 论坛| 古丈县| 沙河市| 巩义市| 聂荣县| 宝山区| 龙山县| 鹰潭市| 咸丰县| 日土县| 许昌市| 新乡市| 沾益县| 公主岭市| 甘孜县| 开鲁县| 塔城市| 孟连| 阿克| 微山县| 平陆县| 吉安县| 丹东市| 东安县| 黔西县| 长沙市| 河东区| 竹溪县| 阿城市| 元氏县| 都匀市| 峡江县| 垫江县| 兴国县| 越西县| 曲沃县| 砚山县|