日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

設計之魅:高質量面向對象設計的秘密

來源: 責編: 時間:2023-12-08 09:14:24 241觀看
導讀設計模式是在軟件設計中用于解決常見問題的經過驗證的解決方案。設計模式并不是代碼或庫,而是一種解決問題的思考方式。在使用設計模式時,需要考慮一些基本的設計原則,這些原則有助于構建靈活、可維護和可擴展的軟件系統

jqf28資訊網——每日最新資訊28at.com

設計模式是在軟件設計中用于解決常見問題的經過驗證的解決方案。設計模式并不是代碼或庫,而是一種解決問題的思考方式。在使用設計模式時,需要考慮一些基本的設計原則,這些原則有助于構建靈活、可維護和可擴展的軟件系統。以下是一些常見的設計原則:jqf28資訊網——每日最新資訊28at.com

單一職責原則(Single Responsibility Principle - SRP):

它指導我們確保一個類只有一個責任。類的責任應該是單一的,即一個類應該只有一個引起它變化的原因。這有助于提高類的內聚性,使得類更加容易理解、修改和維護。jqf28資訊網——每日最新資訊28at.com

// 違反單一職責原則的例子class Report {    private String title;    private String content;    public Report(String title, String content) {        this.title = title;        this.content = content;    }    public void generateReport() {        // 生成報告的業務邏輯        System.out.println("Generating report for " + title + " with content: " + content);    }    public void saveToFile() {        // 將報告保存到文件的業務邏輯        String filename = title.replace(" ", "_") + ".txt";        // 實際保存到文件的代碼略        System.out.println("Report saved to " + filename);    }}// 遵循單一職責原則的例子class Report {    private String title;    private String content;    public Report(String title, String content) {        this.title = title;        this.content = content;    }    public void generateReport() {        // 生成報告的業務邏輯        System.out.println("Generating report for " + title + " with content: " + content);    }}class FileSaver {    public static void saveToFile(Report report) {        // 將報告保存到文件的業務邏輯        String filename = report.getTitle().replace(" ", "_") + ".txt";        // 實際保存到文件的代碼略        System.out.println("Report saved to " + filename);    }}// 上述例子中,Report 類負責生成報告,而 FileSaver 類負責將報告保存到文件。這樣,每個類都有一個清晰的責任,遵循了單一職責原則。

在上述例子中,第一個示例中的 Report 類違反了單一職責原則,因為它負責生成報告和保存報告到文件兩個不同的責任。在第二個示例中,將這兩個責任分別放在 Report 類和 FileSaver 類中,遵循了單一職責原則,使得每個類都更加簡單和可維護。這樣的設計有助于將系統的不同部分解耦,提高代碼的靈活性和可擴展性。jqf28資訊網——每日最新資訊28at.com

一個類應該只有一個引起變化的原因。換句話說,一個類應該只有一個責任。jqf28資訊網——每日最新資訊28at.com

開放/封閉原則(Open/Closed Principle - OCP):

由勃蘭特·梅耶(Bertrand Meyer)提出。該原則表明一個軟件實體(類、模塊、函數等)應該對擴展開放,對修改關閉。簡而言之,當需要添加新功能時,應該通過擴展而不是修改現有代碼來實現。jqf28資訊網——每日最新資訊28at.com

具體來說,開放/封閉原則的核心思想是:jqf28資訊網——每日最新資訊28at.com

開放(Open):

軟件實體應該可以在不修改它的源代碼的情況下進行擴展。jqf28資訊網——每日最新資訊28at.com

新功能應該通過添加新代碼來實現,而不是通過修改已有代碼。jqf28資訊網——每日最新資訊28at.com

封閉(Closed):

已有的軟件實體不應該被修改,因為修改可能引入新的錯誤或影響現有功能的穩定性。jqf28資訊網——每日最新資訊28at.com

這樣的設計使得系統更加穩定,因為不需要修改現有代碼,只需要添加新的代碼。這也有助于降低代碼的耦合性,提高代碼的可維護性和可擴展性。jqf28資訊網——每日最新資訊28at.com

// 違反開放/封閉原則的例子class Rectangle {    public double width;    public double height;    public Rectangle(double width, double height) {        this.width = width;        this.height = height;    }}class AreaCalculator {    public double calculateRectangleArea(Rectangle rectangle) {        return rectangle.width * rectangle.height;    }}// 上述代碼違反了開放/封閉原則,如果要添加一個新的形狀(例如圓形),就需要修改 AreaCalculator 類。// 遵循開放/封閉原則的例子interface Shape {    double calculateArea();}class Rectangle implements Shape {    private double width;    private double height;    public Rectangle(double width, double height) {        this.width = width;        this.height = height;    }    @Override    public double calculateArea() {        return width * height;    }}class Circle implements Shape {    private double radius;    public Circle(double radius) {        this.radius = radius;    }    @Override    public double calculateArea() {        return Math.PI * radius * radius;    }}class AreaCalculator {    public double calculateShapeArea(Shape shape) {        return shape.calculateArea();    }}// 上述代碼遵循了開放/封閉原則,通過引入 Shape 接口和不同的形狀類,可以輕松地添加新的形狀而無需修改 AreaCalculator 類。

在遵循開放/封閉原則的例子中,通過引入一個 Shape 接口和不同的形狀類(例如 Rectangle 和 Circle),可以輕松地添加新的形狀而無需修改 AreaCalculator 類。這樣,系統的擴展性得到了提高,同時保持了對現有代碼的封閉性。jqf28資訊網——每日最新資訊28at.com

軟件實體(類、模塊、函數等)應該對擴展開放,對修改關閉。這意味著在不修改現有代碼的情況下,可以通過添加新的代碼來擴展系統的功能。jqf28資訊網——每日最新資訊28at.com

里氏替換原則(Liskov Substitution Principle - LSP):

由計算機科學家巴巴拉·利斯科夫(Barbara Liskov)提出。該原則指導著子類型(派生類或子類)如何與基類型(基類或父類)進行替換,以確保程序的正確性和一致性。jqf28資訊網——每日最新資訊28at.com

如果對每一個類型為 S 的對象 o1,都有類型為 T 的對象 o2,使得以 T 定義的所有程序 P 在所有的對象 o1 都替換成 o2 時,程序 P 的行為沒有發生變化,那么類型 S 是類型 T 的子類型。jqf28資訊網——每日最新資訊28at.com

換句話說,如果子類型可以替換父類型而不影響程序的正確性,那么這個子類型是符合里氏替換原則的。jqf28資訊網——每日最新資訊28at.com

// 違反里氏替換原則的例子class Rectangle {    protected int width;    protected int height;    public void setWidth(int width) {        this.width = width;    }    public void setHeight(int height) {        this.height = height;    }    public int calculateArea() {        return width * height;    }}class Square extends Rectangle {    @Override    public void setWidth(int width) {        super.setWidth(width);        super.setHeight(width);    }    @Override    public void setHeight(int height) {        super.setHeight(height);        super.setWidth(height);    }}// 上述代碼違反了里氏替換原則,因為在Square類中重寫了setWidth和setHeight方法,導致Square對象在替換Rectangle對象時可能會引發意料之外的行為。// 遵循里氏替換原則的例子class Shape {    protected int width;    protected int height;    public void setWidth(int width) {        this.width = width;    }    public void setHeight(int height) {        this.height = height;    }    public int calculateArea() {        return width * height;    }}class Rectangle extends Shape {    // 省略特有的方法或屬性}class Square extends Shape {    @Override    public void setWidth(int side) {        super.setWidth(side);        super.setHeight(side);    }    @Override    public void setHeight(int side) {        super.setHeight(side);        super.setWidth(side);    }}// 上述代碼遵循了里氏替換原則,因為Square類繼承自Shape類,沒有修改基類的行為,而是通過適當的方式擴展了基類的功能。

在遵循里氏替換原則的例子中,Square類不再繼承自Rectangle類,而是繼承自一個通用的Shape類,確保子類型可以被替換而不引起意外的行為變化。通過這種方式,程序可以更靈活地使用不同的形狀類型,而不必擔心替換時可能引發的問題。jqf28資訊網——每日最新資訊28at.com

子類型必須能夠替換其基類型而不改變程序的正確性。如果一個類是某個抽象類的子類,那么它應該能夠替代該抽象類的任何地方,并且程序的行為不會改變。jqf28資訊網——每日最新資訊28at.com

依賴倒置原則(Dependency Inversion Principle - DIP):

由羅伯特·馬丁(Robert C. Martin)提出。該原則主要有兩個核心觀點:jqf28資訊網——每日最新資訊28at.com

  • 高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象。
  • 抽象不應該依賴于細節,細節應該依賴于抽象。

在設計系統時,應該通過依賴于抽象而不是具體實現來減少模塊之間的耦合。高層模塊和低層模塊都應該依賴于通用的抽象,而不是彼此直接依賴。這有助于提高系統的靈活性、可維護性和可擴展性。jqf28資訊網——每日最新資訊28at.com

// 違反依賴倒置原則的例子class LightBulb {    public void turnOn() {        System.out.println("LightBulb: Bulb turned on...");    }    public void turnOff() {        System.out.println("LightBulb: Bulb turned off...");    }}class Switch {    private LightBulb bulb;    public Switch() {        this.bulb = new LightBulb();    }    public void operate() {        if (bulb != null) {            if (bulb.isOn()) {                bulb.turnOff();            } else {                bulb.turnOn();            }        }    }}// 上述代碼違反了依賴倒置原則,因為Switch類直接依賴于具體的LightBulb類。// 遵循依賴倒置原則的例子interface Switchable {    void turnOn();    void turnOff();}class LightBulb implements Switchable {    @Override    public void turnOn() {        System.out.println("LightBulb: Bulb turned on...");    }    @Override    public void turnOff() {        System.out.println("LightBulb: Bulb turned off...");    }}class Switch {    private Switchable device;    public Switch(Switchable device) {        this.device = device;    }    public void operate() {        if (device != null) {            if (device.isOn()) {                device.turnOff();            } else {                device.turnOn();            }        }    }}// 上述代碼遵循了依賴倒置原則,Switch類依賴于通用的Switchable接口而不是具體的LightBulb類。

在遵循依賴倒置原則的例子中,Switch 類不再直接依賴于 LightBulb 類,而是依賴于通用的 Switchable 接口。這樣,如果有其他類實現了 Switchable 接口,可以輕松地替換 LightBulb 類,而不影響 Switch 類的實現。這提高了系統的靈活性和可維護性。jqf28資訊網——每日最新資訊28at.com

高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象。抽象不應該依賴于細節,細節應該依賴于抽象。這促使使用接口或抽象類來減少模塊之間的耦合。jqf28資訊網——每日最新資訊28at.com

接口隔離原則(Interface Segregation Principle - ISP):

接口隔離原則(Interface Segregation Principle - ISP)是面向對象設計中的一個原則,它強調一個類不應該被強迫依賴于它不使用的接口。該原則的目標是防止一個類因為實現了不需要的接口而變得龐大臃腫,降低類的內聚性。jqf28資訊網——每日最新資訊28at.com

接口隔離原則可以通過將大接口拆分成更小的、更具體的接口來實現。具體來說,一個類只應該知道它需要使用的方法,而不需要了解其他不相關的方法。jqf28資訊網——每日最新資訊28at.com

// 違反接口隔離原則的例子interface Worker {    void work();    void eat();}class Robot implements Worker {    @Override    public void work() {        System.out.println("Robot is working...");    }    @Override    public void eat() {        // 空實現,機器人無需進食    }}class Human implements Worker {    @Override    public void work() {        System.out.println("Human is working...");    }    @Override    public void eat() {        System.out.println("Human is eating...");    }}// 上述代碼違反了接口隔離原則,因為Robot類實現了不需要的eat方法。// 遵循接口隔離原則的例子interface Workable {    void work();}interface Eatable {    void eat();}class Robot implements Workable {    @Override    public void work() {        System.out.println("Robot is working...");    }}class Human implements Workable, Eatable {    @Override    public void work() {        System.out.println("Human is working...");    }    @Override    public void eat() {        System.out.println("Human is eating...");    }}// 上述代碼遵循了接口隔離原則,將大接口拆分成Workable和Eatable兩個小接口,類只需要實現它們真正需要的接口。

在遵循接口隔離原則的例子中,將大接口拆分成 Workable 和 Eatable 兩個小接口。這樣,Robot 類只需實現 Workable 接口,而 Human 類則同時實現了 Workable 和 Eatable 接口。這避免了類實現不需要的方法,提高了系統的靈活性和可維護性。jqf28資訊網——每日最新資訊28at.com

不應該強迫客戶端依賴于它們不使用的接口。一個類不應該被迫實現它用不到的接口。jqf28資訊網——每日最新資訊28at.com

合成/聚合復用原則(Composition/Aggregation Reuse Principle - CARP):

合成/聚合復用原則(Composition/Aggregation Reuse Principle - CARP)是面向對象設計中的一個原則,它強調在復用時優先使用組合(Composition)和聚合(Aggregation),而不是繼承。該原則的核心思想是通過將現有的類組合在一起來創建新的類,而不是通過繼承現有類。jqf28資訊網——每日最新資訊28at.com

合成/聚合復用原則的主要原則有兩個:jqf28資訊網——每日最新資訊28at.com

優先使用合成(Composition):

通過將對象組合在一起來創建新的對象,而不是通過繼承現有類。這樣可以更靈活地構建對象的行為,而不會產生繼承鏈的問題。jqf28資訊網——每日最新資訊28at.com

優先使用聚合(Aggregation):

聚合是一種特殊的合成關系,表示一種“整體-部分”的關系,但整體和部分之間的生命周期可以獨立存在。這允許部分對象在沒有整體對象的情況下存在。與合成一樣,聚合也提供了更靈活的復用方式。jqf28資訊網——每日最新資訊28at.com

// 違反合成/聚合復用原則的例子class Engine {    public void start() {        System.out.println("Engine starting...");    }}class Car extends Engine {    public void drive() {        System.out.println("Car is driving...");    }}// 上述代碼違反了合成/聚合復用原則,因為Car類通過繼承Engine類,導致Car和Engine之間形成了緊耦合的關系。// 遵循合成/聚合復用原則的例子class Engine {    public void start() {        System.out.println("Engine starting...");    }}class Car {    private Engine engine;    public Car(Engine engine) {        this.engine = engine;    }    public void drive() {        engine.start();        System.out.println("Car is driving...");    }}// 上述代碼遵循了合成/聚合復用原則,Car類通過組合引入了Engine類,而不是通過繼承。這降低了類之間的耦合性,使得系統更加靈活。

在遵循合成/聚合復用原則的例子中,Car 類通過組合引入了 Engine 類,而不是通過繼承。這降低了類之間的耦合性,使得系統更加靈活,更容易進行復用和維護。使用合成和聚合的方式可以避免繼承鏈的問題,并提高系統的靈活性。jqf28資訊網——每日最新資訊28at.com

首選使用合成/聚合,而不是繼承。通過將現有類的實例組合到新的類中,而不是通過繼承現有類來實現代碼復用。jqf28資訊網——每日最新資訊28at.com

迪米特法則(Law of Demeter - LoD):

迪米特法則(Law of Demeter - LoD),也被稱為最少知識原則,是面向對象設計中的一項原則。迪米特法則強調一個對象應該對其他對象有最少的了解,即一個類不應該直接與其他類過多地發生相互作用。jqf28資訊網——每日最新資訊28at.com

一個對象應該對其他對象保持最少的了解。只與你的直接朋友通信,而避免和陌生人通信。jqf28資訊網——每日最新資訊28at.com

這意味著一個類應該盡量減少對其他類的引用,盡量減少依賴關系,以降低類之間的耦合度。通過保持對象之間的關系簡單,可以提高系統的靈活性和可維護性。jqf28資訊網——每日最新資訊28at.com

// 違反迪米特法則的例子class Teacher {    public void instruct(Student student) {        // 教師直接與學生對象發生交互        student.study();    }}class Student {    public void study() {        System.out.println("Student is studying...");    }}// 上述代碼違反了迪米特法則,因為Teacher類直接與Student類發生了交互。// 遵循迪米特法則的例子class Teacher {    public void instruct(StudentProxy studentProxy) {        // 教師只與學生代理對象發生交互,而不直接與學生對象交互        studentProxy.study();    }}class Student {    public void study() {        System.out.println("Student is studying...");    }}class StudentProxy {    private Student student;    public StudentProxy(Student student) {        this.student = student;    }    public void study() {        // 通過代理對象轉發請求給學生對象        student.study();    }}// 上述代碼遵循了迪米特法則,Teacher類只與StudentProxy類發生交互,而不直接與Student類發生交互。

在遵循迪米特法則的例子中,Teacher 類只與 StudentProxy 類發生交互,而不直接與 Student 類發生交互。這樣,Teacher 類不需要了解 Student 類的內部實現,通過 StudentProxy 類進行間接的交互。這降低了類之間的耦合度,符合迪米特法則的要求。jqf28資訊網——每日最新資訊28at.com

一個軟件實體應當盡可能少地與其他實體發生相互作用。也被稱為最少知識原則。jqf28資訊網——每日最新資訊28at.com

在面向對象設計中,設計原則是指導我們創建靈活、可維護、可擴展軟件系統的重要指導方針。每個設計原則都強調特定的方面,例如單一職責原則、開放/封閉原則、里氏替換原則、依賴倒置原則、接口隔離原則和合成/聚合復用原則。這些原則共同構建了一個強大的設計基礎,有助于在面對不斷變化的需求時更好地應對挑戰。jqf28資訊網——每日最新資訊28at.com

在實際開發中,理解并應用這些設計原則是至關重要的。它們提供了一組指導原則,幫助自己構建出更加健壯和靈活的軟件系統。通過不斷學習和實踐,可以更好地運用這些原則來創建高質量的面向對象設計。jqf28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-39508-0.html設計之魅:高質量面向對象設計的秘密

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 這套分布式IM即時通訊系統如何寫到簡歷上?我給你整理好了!

下一篇: 探索Spring Boot中@PostConstruct的魔法

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 南宫市| 雅江县| 四川省| 金秀| 天门市| 东乌| 九龙县| 来凤县| 许昌市| 普陀区| 容城县| 天镇县| 都江堰市| 简阳市| 正安县| 佛学| 南丰县| 磴口县| 金坛市| 天峻县| 依安县| 平谷区| 盘山县| 汶川县| 京山县| 禄丰县| 平罗县| 保山市| 德兴市| 霍林郭勒市| 铜梁县| 志丹县| 皋兰县| 汝城县| 漠河县| 陇川县| 突泉县| 封开县| 方正县| 专栏| 唐河县|