譯者 | 劉汪洋
審校 | 重樓
對于軟件開發(fā)者而言,編寫可重用的代碼是一項基本而重要的技能。每位工程師都應掌握如何盡可能地提高代碼的復用性。當前,一些開發(fā)人員可能會認為微服務的本質是小而高效,因此他們無需編寫高質量代碼。然而,即便是微服務,在變得龐大時,閱讀和理解代碼的時間成本也會迅速增加至編寫時的十倍。
代碼一開始編寫得不佳,將會大幅增加修復 bug 或添加新功能的工作量。在一些極端情況下,我見證過團隊因代碼質量問題而放棄原有代碼,重新編寫。這不僅浪費了寶貴時間,還可能導致開發(fā)人員承擔責任并失去工作。
本文將介紹經過實踐驗證的提高Java 中代碼可重用性的八條指導原則。
編寫可重用代碼的首要步驟是與團隊一同確立代碼規(guī)范。如果對編碼規(guī)范不能達成共識,代碼很快就會變得混亂不堪。如果團隊成員之間意見不統(tǒng)一,關于代碼實現(xiàn)的無效討論也會頻繁發(fā)生。同時,你需要確立一個基礎的代碼設計框架,以解決軟件需要解決的問題。
在制定了標準和代碼設計框架之后,接下來應當明確代碼指導原則。
常見的指導原則包括:
一旦團隊就這些規(guī)范達成共識,每個成員都應對代碼審查負責,以確保編寫出高質量、可重用的代碼。如果沒有共識,寫出高質量且可重用的代碼幾乎不可能。
當創(chuàng)建服務并以 API 形式公開時,應該詳細記錄 API 信息,以便新加入的開發(fā)人員能夠輕松理解和使用。
API 在微服務架構中扮演著重要角色。因此,對你的項目不太熟悉的其他團隊成員必須能夠通過閱讀 API 文檔來理解其功能。如果 API 文檔記錄不當,代碼的重復編寫風險會增加。新開發(fā)人員可能會無意中創(chuàng)建一個和現(xiàn)有功能重復的方法。
因此,精確記錄 API 至關重要。但在代碼中過度使用文檔可能并無益處。應該只記錄 API 中的關鍵信息,如業(yè)務操作的解釋、參數(shù)、返回值對象等。
簡潔且具有描述性的代碼命名總是優(yōu)于晦澀難懂的縮寫。瀏覽不熟悉的代碼庫時,我發(fā)現(xiàn)縮寫往往難以讓人立即理解其含義。
因此,相較于使用像Ctr這樣的縮寫,直接命名為Customer更為明晰和有意義。Ctr可能代表了合同(contract)、控制(control)、客戶(customer)等多種含義,使人難以確定其準確意圖。
此外,要遵循你所使用編程語言的命名規(guī)范。以 Java 為例,它有 JavaBeans 命名規(guī)范,這對每個 Java 開發(fā)者來說都是基本常識。以下是 Java 中類、方法、變量和包的命名方式:
內聚的代碼應該專注于_做好一件事_。雖然這是一個簡單的概念,但即便是經驗豐富的開發(fā)人員也常常忽視它。這樣,他們就會創(chuàng)建出所謂的_超級復雜類_,即一個承擔了過多職責的類,有時也被稱為_全能類_。
要實現(xiàn)高內聚的代碼,關鍵是學會拆分代碼,確保每個類和方法專注于單一職責。比如,如果你創(chuàng)建了一個名為saveCustomer的方法,它應當只負責一個動作:保存客戶信息。它不應該同時負責更新和刪除客戶信息。
同理,如果有一個名為CustomerService的類,它應該僅包含與客戶相關的功能。如果CustomerService類中有執(zhí)行產品相關操作的方法,應移至ProductService類中。
與其在CustomerService類中添加執(zhí)行產品操作的方法,不如在該類中引用ProductService,并調用我們所需的任何方法。
為了更清晰地介紹這個概念,我們來分析一個低內聚的類示例:
public class CustomerPurchaseService { public void saveCustomerPurchase(CustomerPurchase customerPurchase) { // 執(zhí)行與客戶相關的操作 registerProduct(customerPurchase.getProduct()); // 更新客戶信息 // 刪除客戶信息 } private void registerProduct(Product product) { // 在客戶領域中執(zhí)行對產品的邏輯操作… }}
這個類存在以下問題:
識別出這些問題后,我們可以重新編寫這段代碼,使其變得更加內聚。我們將registerProduct方法移動到更合適的位置,即ProductService類中。這樣做使代碼更易于搜索和重用,同時避免將此方法局限在CustomerPurchaseService中:
public class CustomerPurchaseService { private ProductService productService; public CustomerPurchaseService(ProductService productService) { this.productService = productService; } public void saveCustomerPurchase(CustomerPurchase customerPurchase) { // 僅執(zhí)行與客戶購買相關的操作 productService.registerProduct(customerPurchase.getProduct()); }}public class ProductService { public void registerProduct(Product product) { // 在產品領域中執(zhí)行相關邏輯… }}
在這個改進后的版本中,saveCustomerPurchase僅執(zhí)行其主要職責:保存客戶購買信息。同時,registerProduct方法的職責被正確地委托給了ProductService類,從而使兩個類都更加專注和內聚。現(xiàn)在,這些類及其方法都專注于執(zhí)行預期的特定任務。
_高度耦合的代碼_指的是那些具有過多依賴關系的代碼,這種情況會導致代碼難以維護。類中定義的依賴(其他類)越多,其耦合程度就越高。
微服務架構的目標之一就是將服務解耦,如果一個微服務與其他服務都有連接,那么它就會高度耦合。
想要更好地實現(xiàn)代碼復用,就需要盡可能使系統(tǒng)和代碼各自獨立。雖然服務和代碼之間的通信不可避免會產生一定程度的耦合,但關鍵在于讓這些服務盡可能保持獨立性。
下面是一個高度耦合類的例子:
public class CustomerOrderService { private ProductService productService; private OrderService orderService; private CustomerPaymentRepository customerPaymentRepository; private CustomerDiscountRepository customerDiscountRepository; private CustomerContractRepository customerContractRepository; private CustomerOrderRepository customerOrderRepository; private CustomerGiftCardRepository customerGiftCardRepository; // 其他方法…}
注意CustomerService類與許多其他服務類的耦合程度很高。這么多的依賴意味著該類將包含大量代碼,這不利于代碼的測試和維護。
更有效的方法是拆分這個類,創(chuàng)造多個依賴更少的服務。我們可以通過將CustomerService類分解為獨立的服務來降低其耦合度:
public class CustomerOrderService { private OrderService orderService; private CustomerPaymentService customerPaymentService; private CustomerDiscountService customerDiscountService; // 省略其他方法…}public class CustomerPaymentService { private ProductService productService; private CustomerPaymentRepository customerPaymentRepository; private CustomerContractRepository customerContractRepository; // 省略其他方法…}public class CustomerDiscountService { private CustomerDiscountRepository customerDiscountRepository; private CustomerGiftCardRepository customerGiftCardRepository; // 省略其他方法…}
經過這樣的重構,CustomerService及其他類變得更易于進行單元測試,同時也更便于維護。類的職責越單一且清晰,就越容易實現(xiàn)新功能。如果出現(xiàn) bug,也更容易進行修復。
SOLID 代表面向對象編程(OOP)中五個關鍵的設計原則,它們的目標是使軟件系統(tǒng)更加可維護、靈活,并易于理解。
下面是這些原則的簡要說明:
遵循這些 SOLID 原則有助于開發(fā)者編寫更模塊化、可維護且易于擴展的代碼。這些原則有助于實現(xiàn)更易于理解、測試和修改的代碼,從而形成更健壯、適應性更強的軟件系統(tǒng)。
設計模式是經驗豐富的開發(fā)者在處理多種編碼場景后總結出的最佳實踐。恰當?shù)厥褂迷O計模式可以顯著提升代碼的復用性。
掌握設計模式還能增強你閱讀和理解代碼的能力——這包括 JDK 中的代碼。當你能識別出其背后的設計模式時,代碼會變得更加清晰。
盡管設計模式有其用處,但并非每種模式適用于所有情況,因此使用時需謹慎。僅僅因為我們了解某個模式,并不意味著就應該隨意應用。在不恰當?shù)膱鼍爸惺褂迷O計模式可能會使代碼變得更復雜、更難以維護。然而,在合適的場合應用設計模式,可以使代碼更加靈活和易于擴展。
以下是面向對象編程中常見的設計模式簡要概述:
并不需要記住每一種設計模式,重要的是意識到這些模式的存在,并理解它們各自的使用場景。這樣,你就能夠根據(jù)具體的編程情境選擇最合適的設計模式。
許多公司在沒有充分理由的情況下仍選擇使用內部框架,但這對非大型科技公司來說通常是不現(xiàn)實的。對于中小型企業(yè)來說,與開源社區(qū)或大型科技公司競爭,開發(fā)出更優(yōu)解決方案的可能性較低。
相比于重復發(fā)明輪子和制造不必要的工作,更理智的選擇是直接利用已有的工具和技術。這不僅節(jié)省時間,還有助于開發(fā)人員的職業(yè)發(fā)展,因為他們無需學習只在公司內部使用的框架。
例如,Hibernate 是一個經過嚴格測試并被廣泛使用的持久性框架。我遇到過的一家公司選擇使用自己的內部框架進行持久化處理,盡管它并不具備 Hibernate 的全部功能和穩(wěn)定性。維護和擴展這種內部框架給公司帶來了額外負擔,而沒有帶來相應的好處。
因此,建議盡可能使用市場上廣泛可用且流行的技術和工具。開發(fā)一個能與成熟開源軟件匹敵的框架幾乎不可能,因為后者是眾多才華橫溢的開發(fā)者多年合作的成果。此外,許多大型公司也支持開源項目,確保它們能按預期運行。
理解和應用代碼復用性的關鍵原則對于構建高效且可維護的軟件系統(tǒng)至關重要。通過掌握抽象、封裝、關注點分離、標準化和文檔化等關鍵概念,開發(fā)人員能創(chuàng)建可節(jié)省時間和減少重復工作的組件,同時提升代碼質量。
設計模式對代碼復用至關重要,提供了針對常見設計問題的經過驗證過的解決方案。內聚性和低耦合確保組件獨立且依賴性最小,提高了它們的復用性。遵循 SOLID 原則有助于創(chuàng)建模塊化、可擴展的代碼,易于集成到不同項目中。
編寫可復用代碼能夠為開發(fā)人員帶來諸多好處,包括提高生產力、加強協(xié)作和加快開發(fā)周期。可復用代碼使項目迭代更快、維護更容易,能夠有效利用現(xiàn)有解決方案。總之,掌握代碼復用性的核心原則能夠幫助開發(fā)人員構建可擴展、適應性強且面向未來的軟件系統(tǒng)。
劉汪洋,51CTO社區(qū)編輯,昵稱:明明如月,一個擁有 5 年開發(fā)經驗的某大廠高級 Java 工程師,擁有多個主流技術博客平臺博客專家稱號。
原文標題:How to write reusable Java code,作者:Rafael del Nero
本文鏈接:http://www.www897cc.com/showinfo-26-56565-0.html如何提高 Java 代碼的可重用性
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com