国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 Java java教程 堅實的原則

堅實的原則

Oct 21, 2024 am 06:12 AM

SOLID Principles

SOLID 是一組基本原則,旨在增強面向?qū)ο缶幊?(OOP) 中代碼的可管理性和可擴展性。它由五個關(guān)鍵原則組成:

  1. S單一責(zé)任原則?—?SRP
  2. O筆閉原則?—?OCP
  3. L伊斯科夫替代原理?—?LSP
  4. I接口隔離原則?—?ISP
  5. D 依存倒置原理?—?DIP

這些原則是由 Robert C. Martin(也稱為 Uncle Bob)在 2000 年代初期提出的,此后已在軟件開發(fā)社區(qū)中廣泛采用。通過遵循 SOLID 原則,開發(fā)人員可以創(chuàng)建更易于理解、修改和擴展的代碼,從而形成更健壯和可維護的軟件系統(tǒng)。

單一職責(zé)原則(SRP)

單一職責(zé)原則是 OOP 和 SOLID 中第一個也是最基本的原則。顧名思義,這一原則的意思是“一個類應(yīng)該只負(fù)責(zé)一個特定的責(zé)任”。

假設(shè)我們有一個名為 Invoice 的類,其中包含 2 個方法generateInvoice() 和 saveToFiles() 。

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }

  public void saveToFiles() {
    // code to save invoice as a file.
  }
}

這不是一個好的做法,因為 Invoice 類有兩個職責(zé)。更好的方法是將這些功能分離到專用的類中。

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }
}

public class FileManager {
  public void saveToFiles(Invoice invoice) {
    // code to save invoice as a file.
  }
}

在這里,我們可以看到我們有 2 個用于用例的類:

  • 生成發(fā)票
  • 保存到文件

遵循 SRP 的好處

  • 改進的代碼組織:通過將關(guān)注點分成不同的類,代碼庫變得更有組織性并且更易于導(dǎo)航。
  • 更好的可維護性:當(dāng)一個類具有單一職責(zé)時,更容易理解其目的并進行更改,而不會產(chǎn)生意想不到的副作用。
  • 提高可重用性:具有單一職責(zé)的類更有可能在應(yīng)用程序的不同部分甚至其他項目中重用。
  • 更容易測試:具有單一職責(zé)的類通常更小、更集中,使它們更容易單獨測試。

開閉原則(OCP)

開閉原則是SOLID的另一個核心原則。該原則由 Bertrand Meyer 于 1997 年提出。該原則背后的想法是“軟件工件(類、模塊和函數(shù))應(yīng)該對擴展開放,但對修改關(guān)閉?!?/p>

例如;

比方說,我們有一個名為 Shape 的類,我們可以使用這個類來計算形狀的面積。

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }

  public void saveToFiles() {
    // code to save invoice as a file.
  }
}

在上面的代碼中,添加新形狀需要修改現(xiàn)有的 Shape 類,這不是一個好的做法。

下面是一個代碼示例,演示了如何將開閉原則應(yīng)用于此場景。

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }
}

public class FileManager {
  public void saveToFiles(Invoice invoice) {
    // code to save invoice as a file.
  }
}

通過OCP的應(yīng)用,我們可以在不修改當(dāng)前實現(xiàn)的情況下添加許多我們想要的形狀。

注意:使用接口并不是實現(xiàn) OCP 的唯一方法。

遵循 OCP 的好處

  • 降低錯誤風(fēng)險:通過不修改現(xiàn)有代碼,可以最大限度地降低引入新錯誤或破壞現(xiàn)有功能的風(fēng)險。
  • 提高可維護性:遵循 OCP 的代碼更容易維護和擴展,因為可以在不更改現(xiàn)有代碼庫的情況下添加新功能。
  • 增強靈活性:抽象和多態(tài)性的使用允許更靈活和適應(yīng)性更強的設(shè)計,從而更容易適應(yīng)不斷變化的需求。

里氏替換原理 (LSP)

里氏替換原則是 OOP 中的另一個重要原則。它是由 Barbara Liskov 于 1987 年在一次關(guān)于數(shù)據(jù)抽象的會議演講中引入的。

該原則指出,“超類的對象應(yīng)該可以用其子類的對象替換,而不改變程序的正確性”。

例如,如果 Circle 和 Rectangle 是 Shape 的子類型,那么我們應(yīng)該能夠用 Circle 或 Rectangle 對象替換 Shape 對象,不會出現(xiàn)任何問題。

public class Shape {
    private String shapeType;
    private double radius;
    private double length;
    private double width;

    public Shape(String shapeType, double radius, double length, double width) {
        this.shapeType = shapeType;
        this.radius = radius;
        this.length = length;
        this.width = width;
    }

    public double area() {
        if (shapeType.equals("circle")) {
            return Math.PI * (radius * radius);
        } else if (shapeType.equals("rectangle")) {
            return length * width;
        } else {
            throw new IllegalArgumentException("Unknown shape type");
        }
    }
}

// Usage
public class Main {
    public static void main(String[] args) {
        Shape circle = new Shape("circle", 5, 0, 0);
        Shape rectangle = new Shape("rectangle", 0, 4, 6);

        System.out.println(circle.area());
        System.out.println(rectangle.area());
    }
}

如本例所示,遵循里氏替換原則意味著我們應(yīng)該能夠無縫地用子類實例替換超類實例。

遵循 LSP 的好處

  • 改進的代碼可重用性:通過確保子類型可以替換其基本類型,使用基本類型的代碼也可以與其任何子類型一起使用,從而促進代碼重用。
  • 增強的可維護性:遵循LSP的代碼更容易維護,因為它降低了修改或擴展代碼庫時引入錯誤的風(fēng)險。
  • 更好的可測試性:LSP 使為類及其子類型編寫單元測試變得更加容易,因為測試可以針對基本類型編寫,并且應(yīng)該適用于所有子類型。

接口隔離原則(ISP)

接口隔離原則是 Robert C. Martin 提出的五個 SOLID 原則之一。它指出:“不應(yīng)強迫客戶端依賴他們不使用的接口”。

換句話說,使用多個特定于任務(wù)的接口比使用一個通用接口更好。

下面的示例展示了通用接口的用法。

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }

  public void saveToFiles() {
    // code to save invoice as a file.
  }
}

使用像 MultifunctionPrinter 這樣的通用接口迫使我們實現(xiàn)不必要的方法,這被認(rèn)為是不好的做法。讓我們探討一下如何將接口隔離原則應(yīng)用于此場景。

接口

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }
}

public class FileManager {
  public void saveToFiles(Invoice invoice) {
    // code to save invoice as a file.
  }
}

實施

public class Shape {
    private String shapeType;
    private double radius;
    private double length;
    private double width;

    public Shape(String shapeType, double radius, double length, double width) {
        this.shapeType = shapeType;
        this.radius = radius;
        this.length = length;
        this.width = width;
    }

    public double area() {
        if (shapeType.equals("circle")) {
            return Math.PI * (radius * radius);
        } else if (shapeType.equals("rectangle")) {
            return length * width;
        } else {
            throw new IllegalArgumentException("Unknown shape type");
        }
    }
}

// Usage
public class Main {
    public static void main(String[] args) {
        Shape circle = new Shape("circle", 5, 0, 0);
        Shape rectangle = new Shape("rectangle", 0, 4, 6);

        System.out.println(circle.area());
        System.out.println(rectangle.area());
    }
}

通過應(yīng)用ISP,我們將其分成更小的、特定于角色的接口?——例如打印機、掃描儀和傳真。這允許每個類(例如 BasicPrinter、AdvancedPrinter 或 FaxMachine)僅實現(xiàn)相關(guān)功能,從而促進模塊化并減少不必要的依賴關(guān)系。

跟隨 ISP 的好處

  • 模塊化和可重用代碼:通過將大型接口分解為更小、更具體的接口,代碼變得更加模塊化和可重用。類或模塊可以僅實現(xiàn)它們需要的接口,從而減少不必要的依賴關(guān)系,并使在系統(tǒng)的不同部分之間重用代碼變得更容易。
  • 降低代碼復(fù)雜度:當(dāng)類或模塊僅依賴于它們所需的接口時,代碼變得不那么復(fù)雜且更容易理解。這是因為開發(fā)人員不必處理不必要的方法或依賴項。這些與其特定用例無關(guān)。
  • 提高可維護性:通過更小、更集中的界面,可以更輕松地維護代碼。對一個界面的更改不太可能影響系統(tǒng)的其他部分,從而降低了引入錯誤或破壞現(xiàn)有功能的風(fēng)險。
  • 更好的可測試性:更小、更集中的界面使得為各個組件編寫單元測試變得更容易。這是因為測試可以專注于特定的行為,而不會受到不相關(guān)的方法或依賴項的影響。
  • 增加靈活性:通過遵守ISP,系統(tǒng)變得更加靈活并且更容易擴展或修改。可以通過創(chuàng)建新接口或修改現(xiàn)有接口來添加新功能或要求,而不會影響整個系統(tǒng)。

依賴倒置原則(DIP)

依賴倒置原則是SOLID的最終原則。這也是由 Robert C. Martin 介紹的。這促進了松散耦合的代碼。

DIP說明了幾點:

  • 高層模塊不應(yīng)該依賴于低層模塊。
  • 兩者都應(yīng)該依賴于抽象。
  • 抽象不應(yīng)該依賴于細(xì)節(jié)。
  • 細(xì)節(jié)應(yīng)該取決于抽象。

簡單來說,一個類不應(yīng)該直接依賴于其他特定類(具體實現(xiàn)),而應(yīng)該依賴于接口或抽象類。這使得代碼更加靈活且更易于維護,因為您可以在不更改依賴類的情況下更換實現(xiàn)。

緊耦合代碼(無 DIP)

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }

  public void saveToFiles() {
    // code to save invoice as a file.
  }
}

如上例所示,Computer 類直接依賴于 Keyboard 類。

松耦合代碼(帶 DIP)

public class Invoice {
  private Long InvoiceNo;

  public void generateInvoice() {
    // code to generate Invoice.
  }
}

public class FileManager {
  public void saveToFiles(Invoice invoice) {
    // code to save invoice as a file.
  }
}

現(xiàn)在,Computer 依賴于 InputDevice 接口,而不是特定的 Keyboard。這樣可以輕松切換到另一個輸入設(shè)備,例如 WirelessKeyboard,而無需修改 Computer 類。

遵循 DIP 的好處

  • 松散耦合:通過依賴抽象而不是具體實現(xiàn),代碼的耦合變得不那么緊密,使得更容易更改系統(tǒng)的一個部分而不影響其他部分。
  • 提高可維護性:低層模塊的變化不會影響高層模塊,使系統(tǒng)更容易維護和擴展。
  • 增強的可測試性:可以使用低級模塊的模擬實現(xiàn)來測試高級模塊,使測試更快、更可靠。
  • 提高可重用性:高層模塊可以在不同的上下文中重用,而不需要更改它們所依賴的低層模塊。

結(jié)論

總而言之,SOLID 原則:單一職責(zé)、開閉、里氏替換、接口隔離和依賴倒置為在面向?qū)ο缶幊讨芯帉懜蓛簟⒖删S護和可擴展的代碼提供了基本準(zhǔn)則。

通過遵守這些原則,開發(fā)人員可以創(chuàng)建更易于理解、修改和擴展的系統(tǒng),最終帶來更高質(zhì)量的軟件和更高效的開發(fā)流程。

概括

感謝您閱讀這篇文章!我希望您現(xiàn)在對 SOLID 原則以及如何應(yīng)用它們來增強您的項目有了深入的了解。

關(guān)注我:
  • LinkedIn?—?@nsadisha
  • GitHub?—?@nsadisha
  • 中?—?@nsadisha
  • Dev.to?—?@nsadisha

—薩迪莎·尼薩拉

以上是堅實的原則的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1602
29
PHP教程
1504
276
Hashmap在Java內(nèi)部如何工作? Hashmap在Java內(nèi)部如何工作? Jul 15, 2025 am 03:10 AM

HashMap在Java中通過哈希表實現(xiàn)鍵值對存儲,其核心在于快速定位數(shù)據(jù)位置。1.首先使用鍵的hashCode()方法生成哈希值,并通過位運算轉(zhuǎn)換為數(shù)組索引;2.不同對象可能產(chǎn)生相同哈希值,導(dǎo)致沖突,此時以鏈表形式掛載節(jié)點,JDK8后鏈表過長(默認(rèn)長度8)則轉(zhuǎn)為紅黑樹提升效率;3.使用自定義類作鍵時必須重寫equals()和hashCode()方法;4.HashMap動態(tài)擴容,當(dāng)元素數(shù)超過容量乘以負(fù)載因子(默認(rèn)0.75)時,擴容并重新哈希;5.HashMap非線程安全,多線程下應(yīng)使用Concu

Java可選示例 Java可選示例 Jul 12, 2025 am 02:55 AM

Optional能清晰表達意圖并減少null判斷的代碼噪音。1.Optional.ofNullable是處理可能為null對象的常用方式,如從map中取值時可結(jié)合orElse提供默認(rèn)值,邏輯更清晰簡潔;2.通過鏈?zhǔn)秸{(diào)用map實現(xiàn)嵌套取值,安全地避免NPE,任一環(huán)節(jié)為null則自動終止并返回默認(rèn)值;3.filter可用于條件篩選,滿足條件才繼續(xù)執(zhí)行后續(xù)操作,否則直接跳到orElse,適合輕量級業(yè)務(wù)判斷;4.不建議過度使用Optional,如基本類型或簡單邏輯中其反而增加復(fù)雜度,部分場景直接返回nu

如何修復(fù)java.io.notserializable Exception? 如何修復(fù)java.io.notserializable Exception? Jul 12, 2025 am 03:07 AM

遇到j(luò)ava.io.NotSerializableException的核心解決方法是確保所有需序列化的類實現(xiàn)Serializable接口,并檢查嵌套對象的序列化支持。1.給主類添加implementsSerializable;2.確保類中自定義字段對應(yīng)的類也實現(xiàn)Serializable;3.用transient標(biāo)記不需要序列化的字段;4.檢查集合或嵌套對象中的非序列化類型;5.查看異常信息定位具體哪個類未實現(xiàn)接口;6.對無法修改的類考慮替換設(shè)計,如保存關(guān)鍵數(shù)據(jù)或使用可序列化的中間結(jié)構(gòu);7.考慮改

如何處理Java中的字符編碼問題? 如何處理Java中的字符編碼問題? Jul 13, 2025 am 02:46 AM

處理Java中的字符編碼問題,關(guān)鍵是在每一步都明確指定使用的編碼。1.讀寫文本時始終指定編碼,使用InputStreamReader和OutputStreamWriter并傳入明確的字符集,避免依賴系統(tǒng)默認(rèn)編碼。2.在網(wǎng)絡(luò)邊界處理字符串時確保兩端一致,設(shè)置正確的Content-Type頭并用庫顯式指定編碼。3.謹(jǐn)慎使用String.getBytes()和newString(byte[]),應(yīng)始終手動指定StandardCharsets.UTF_8以避免平臺差異導(dǎo)致的數(shù)據(jù)損壞。總之,通過在每個階段

Java插座編程基本面和示例 Java插座編程基本面和示例 Jul 12, 2025 am 02:53 AM

JavaSocket編程是網(wǎng)絡(luò)通信的基礎(chǔ),通過Socket實現(xiàn)客戶端與服務(wù)器間的數(shù)據(jù)交換。1.Java中Socket分為客戶端使用的Socket類和服務(wù)器端使用的ServerSocket類;2.編寫Socket程序需先啟動服務(wù)器監(jiān)聽端口,再由客戶端發(fā)起連接;3.通信過程包括連接建立、數(shù)據(jù)讀寫及流關(guān)閉;4.注意事項包括避免端口沖突、正確配置IP地址、合理關(guān)閉資源及支持多客戶端的方法。掌握這些即可實現(xiàn)基本的網(wǎng)絡(luò)通信功能。

Java中的可比較與比較器 Java中的可比較與比較器 Jul 13, 2025 am 02:31 AM

在Java中,Comparable用于類內(nèi)部定義默認(rèn)排序規(guī)則,Comparator用于外部靈活定義多種排序邏輯。1.Comparable是類自身實現(xiàn)的接口,通過重寫compareTo()方法定義自然順序,適用于類有固定、最常用的排序方式,如String或Integer。2.Comparator是外部定義的函數(shù)式接口,通過compare()方法實現(xiàn),適合同一類需要多種排序方式、無法修改類源碼或排序邏輯經(jīng)常變化的情況。兩者區(qū)別在于Comparable只能定義一種排序邏輯且需修改類本身,而Compar

如何在Java的地圖上迭代? 如何在Java的地圖上迭代? Jul 13, 2025 am 02:54 AM

遍歷Java中的Map有三種常用方法:1.使用entrySet同時獲取鍵和值,適用于大多數(shù)場景;2.使用keySet或values分別遍歷鍵或值;3.使用Java8的forEach簡化代碼結(jié)構(gòu)。entrySet返回包含所有鍵值對的Set集合,每次循環(huán)獲取Map.Entry對象,適合頻繁訪問鍵和值的情況;若只需鍵或值,可分別調(diào)用keySet()或values(),也可在遍歷鍵時通過map.get(key)獲取值;Java8中可通過Lambda表達式使用forEach((key,value)-&gt

Java中的'靜態(tài)”關(guān)鍵字是什么? Java中的'靜態(tài)”關(guān)鍵字是什么? Jul 13, 2025 am 02:51 AM

InJava,thestatickeywordmeansamemberbelongstotheclassitself,nottoinstances.Staticvariablesaresharedacrossallinstancesandaccessedwithoutobjectcreation,usefulforglobaltrackingorconstants.Staticmethodsoperateattheclasslevel,cannotaccessnon-staticmembers,

See all articles