项目包装组织
程序包是Java的基本概念,是您開始用該語言編程時偶然發現的第一件事。 作為一個初學者,您可能不太在意軟件包的結構,但是隨著您成為經驗豐富且成熟的軟件開發人員,您開始思考可以采取哪些措施來提高其效率。 有幾個主要選項需要考慮,選擇正確的選項可能不是一個顯而易見的選擇。 本文應該為您提供常用策略的概述。
我們為什么使用包裹?
從語言的角度來看,Java包提供了兩個重要的功能,編譯器可以利用它們。 最明顯的一個是類的名稱空間定義。 幾個名稱完全相同的類可以在一個項目中使用,只要它們屬于不同的包即可將一個類與另一個類區分開。 如果您無法想象如果沒有包,該語言將是什么樣子,那么請看一下JavaScript世界中的模塊化策略。 在ES2015之前,沒有官方標準,而且名稱沖突并非罕見。
第二件事是,程序包允許為項目的特定成員定義訪問修飾符。 對于不同包的成員,可以限制或完全禁止類,接口或其成員(如字段和方法)的可訪問性。
編譯器首先使用這兩個功能來執行語言規則。 對于干凈的編碼人員和軟件技術人員而言,軟件包的主要屬性可能具有有意義的名稱,該名稱描述了軟件包的用途和存在的原因。 對于編譯器,這只是一個隨機的char字符串,而對于我們來說,這是表達我們意圖的另一種方式。
什么是包裹?
在官方Java教程中,我們可以找到以以下形式開頭的定義:
包是一個命名空間,用于組織一組相關的類和接口。 從概念上講,您可以將軟件包視為類似于計算機上的不同文件夾。 您可以將HTML頁面保留在一個文件夾中,將圖像保留在另一個文件夾中,并將腳本或應用程序保留在另一個文件夾中。 (...)
第一句話強調軟件包的組織目的。 但是,該定義沒有說明應該將哪種關系類和接口視為一個單獨的組。 這個問題向所有軟件開發人員開放。 最近,肯特·貝克(Kent Beck)寫了一條一般性建議,該建議也適用于本文中討論的主題:
如果您一直想知道要清除的內容,請將相似的元素靠得更近些,而將不同的元素靠得更近些
—肯特·貝克(@KentBeck) 2017年6月26日
但是,就像上述包裝定義中的“相關”一詞一樣,“相似”一詞對不同的人可能具有完全不同的含義。 在本文的其余部分,我們將在軟件包組織的背景下考慮可能的選項。
逐層包裝
項目類之間最普遍公認的相似之處可能是他們的責任。 使用此屬性進行組織的方法稱為逐層打包或水平切片,實際上,其外觀或多或少類似于下圖。
如果您沒有機會從事具有這種結構的項目,則可以在一些框架教程中找到它。 例如,Play框架建議在2.2版之前使用這種方法。 Angular.js的教程最初建議根據事物的職責將事物保持在一起。
他們改變了對主題的看法,并更新了教程,這一事實可能會讓您想到什么。 但是在判斷解決方案之前,讓我們先看一下它的優缺點。
優點
考慮到分層體系結構是使用最廣泛的體系結構,開發人員旨在將所選的體系結構反映在包結構中也就不足為奇了。 這種方法的長期流行影響了將結構應用到新項目中的決定,因為團隊的新手更容易在他們熟悉的環境中采用他們。
在這樣的應用程序中為新類找到合適的位置實際上是不費吹灰之力的操作。 該結構是在開發之初創建的,在整個項目的存在過程中始終保持不變。 這種簡單性使得即使經驗不足的開發人員也可以使項目保持秩序,因為結構易于理解。
缺點
有人說將所有模型類放在一個位置使它們更易于重用,因為它們可以與整個包一起簡單地復制到另一個項目中。 但是真的是這樣嗎? 特定域模型的形狀通常僅在項目內的有限上下文中有效。 例如,產品類別在購物應用程序中將具有與管理制造商訂單的應用程序不同的屬性。 而且,即使您要使用相同的類,也有必要將它們提取到每個應用程序中標記為依賴項的單獨jar中。 即使存在于獨立但相關的項目中,代碼重復也會導致錯誤,因此我們應避免粘貼粘貼。
逐層打包方法的主要缺點是過度使用了公共訪問修飾符。 現代的IDE默認情況下使用public修飾符創建類和方法,而不會強迫開發人員考慮使用更合適的選項。 實際上,在分層包組織中沒有其他選擇。 僅將存儲庫暴露給單個服務類就要求該存儲庫是公共的。 副作用是,項目中的所有其他類都可以訪問該存儲庫,即使是不應該與其直接通信的層也可以訪問該存儲庫。 這種方法鼓勵創建無法維護的意大利面條代碼,并導致包裝之間的高度耦合。
如今,無論它們位于何處,在IDE中的已連接類之間進行跳轉都非常簡單,但為新功能添加新的類集需要更多的注意。 當類分布在多個目錄中時, 僅通過查看代碼也很難評估功能的復雜性 。
一開始,我們說過程序包的名稱應提供有關其內容的其他詳細信息。 在逐包方法中,所有程序包都描述了解決方案的體系結構,但它們分別沒有提供任何有用的信息。 實際上,在許多情況下,它們會復制其成員的類名中顯示的信息。
按功能包裝
在硬幣的另一面,您可以圍繞要素或領域模型構建類。 您可能已經聽說過這種方法是垂直切片組織。 如果只使用水平切片,乍一看可能看起來有些混亂,但是最后這只是心態問題。 下圖表示與上一段相同的類,但包裝布局不同。
您可能不會只將所有左腳鞋放在一個地方,而就將另一只腳鞋放在同一只腳上。 您要成對穿著鞋子,因為那是您使用鞋子的方式。 同樣,您可以查看項目中的類。
垂直切片的核心思想是將構建特定功能的所有類放在單個程序包中。 遵循此規則,您將獲得一些收益,但同時也會面臨一些負面后果。
優點
當所有要素類都放在一個程序包中時,public access修飾符更具表現力,因為它允許描述要素的哪一部分應由應用程序的其他部分訪問。 在包內,您應該贊成使用package-private修飾符來改善模塊化。 最好在IDE中修改默認模板,以避免創建公共類和方法。 公開一些東西應該是一個有意識的決定。 來自不同程序包的類之間較少的連接將導致更簡潔,更可維護的代碼庫。
在水平切片中,程序包在每個項目中具有相同的名稱集,而在垂直切片方法中, 程序包具有更有意義的名稱,這些名稱描述了它們的功能用途 。 僅通過查看項目結構,您就可以猜測用戶可以使用該應用程序做什么。 該方法還表示要素之間的層次關系。 域的聚合根很容易識別,因為它們存在于軟件包樹的最低級別。 包結構記錄了應用程序。
根據功能對類進行分組可以使包更小,更容易瀏覽。 在橫向方法中,每個新功能都會增加圖層包中的類總數,并使它們更難瀏覽。 在長長的類列表中找到有趣的元素將成為一種低效率的活動。 相反, 僅當擴展了功能時 , 關注該功能的軟件包才會增長 。 新功能在樹的適當節點中接收其自己的包。
還值得一提的是垂直切片包裝的靈活性。 隨著微服務架構的日益普及,擁有已經按功能分割的整體應用程序絕對比將項目按層組織的項目更容易轉換成單獨的服務。 采用按功能打包的方法可以為應用程序的可擴展性增長做好準備。
缺點
隨著項目的發展,軟件包的結構需要更多的注意。 重要的是要了解,隨著應用程序變得越來越復雜,軟件包樹會隨著時間的推移而發展。 您有時會不得不停下來一會兒,并考慮將程序包移動到另一個節點或將其拆分為較小的節點。 結構的清晰度不是免費的。 團隊負責保持其良好狀態,并與該領域的知識保持一致。
了解領域是清潔項目結構的關鍵要素。 為新功能選擇合適的位置可能會遇到問題,特別是對于團隊新手來說,因為這需要了解應用程序背后的業務。 某些人可能會認為這是一種優勢,因為這種方法鼓勵團隊成員之間共享知識。 向該項目介紹新的開發人員比較耗時,但可能會被視為一項投資。
混合方式
您可能認為四肢沒有好處。 我們難道不能僅從兩種方法中取最大的優點,并創造介于兩個極端之間的新質量嗎? 有兩種可能的組合。 程序包的第一層被一層劃分,要素是它們的子級,要素建立在頂層,層是它們的子節點。
第一種選擇是您可能遇到的,因為它是增長到大尺寸包裝的常見解決方案。 它增加了結構的清晰度,但是不幸的是,逐層封裝方法的所有缺點都像以前一樣適用。 最大的問題是,仍然必須在幾乎所有地方都使用public修飾符才能連接您的類和接口。
使用另一個選項,我們應該問一個問題,該解決方案是否真的有意義。 按功能打包的方法支持層的組織,但它是在類級別而不使用package來完成的 。 通過引入其他級別的軟件包,我們將失去利用默認訪問修飾符的能力。 我們在結構上也沒有獲得太多簡化。 如果功能部件包變得無法管理,最好提取一個子功能部件。
摘要
在開始新項目時,選擇包結構是您必須要做的第一選擇。 該決定會影響整個解決方案的未來可維護性。 盡管從理論上講,您可以在任何時間點更改方法,但是通常,這種轉移的總成本只會阻止這種轉移的發生。 這就是為什么在開始時與整個團隊花費幾分鐘并比較可能的選擇尤為重要的原因。 一旦做出選擇,您要做的就是確保每個開發人員都遵循相同的策略。 對于按功能打包的方法而言,這可能會比較困難,尤其是第一次完成時,但是好處列表絕對值得付出努力。
如果您對垂直切面有任何經驗,并且想在主題上增加兩分錢, 請隨時在評論中分享您的想法 。 另外,請考慮與您的同事分享該帖子。 閱讀您的討論結果和對該方法的感受將是很棒的。
翻譯自: https://www.javacodegeeks.com/2017/07/project-package-organization.html
總結
- 上一篇: 1.spring security简单的
- 下一篇: 武大校长开学典礼盛赞华为Mate60 P