首頁  >  文章  >  Java  >  實體導向的開發

實體導向的開發

WBOY
WBOY原創
2024-07-24 16:37:00660瀏覽

Desenvolvimento Orientado a SOLID

在軟體開發中,程式碼維護、擴充和靈活性對於專案的長期成功非常重要。 SOLID 原則的製定是為了指導開發人員創建更易於理解、修改和擴展的程式碼。在本文中,我們將分別討論 SOLID 五個原則以及如何透過 Java 中的實際範例來使用它們。

1. 單一職責原則

單一職責原則(SRP)規定,一個類別必須只有一個改變的理由,即它在系統內必須具有單一職責。

// Antes de aplicar o SRP
class ProductService {
    public void saveProduct(Product product) {
        // Lógica para salvar o produto no banco de dados
    }

    public void sendEmail(Product product) {
        // Lógica para enviar um email sobre o produto
    }
}
// Após aplicar o SRP
class ProductService {
    public void saveProduct(Product product) {
        // Lógica para salvar o produto no banco de dados
    }
}

class EmailService {
    public void sendEmail(Product product) {
        // Lógica para enviar um email sobre o produto
    }
}

在範例中,我們將在資料庫中保存產品的責任與發送有關產品的電子郵件的責任分開。這有利於未來的更改,因為發送電子郵件的更改不再影響產品保存邏輯。

2. 開閉原理

開放/封閉原則(OCP)建議軟體實體(類別、模組、函數等)應該對擴充開放,但對修改關閉。這是透過使用抽象和繼承來實現的。

// Exemplo inicial violando o OCP
class AreaCalculator {
    public double calculateArea(Rectangle[] rectangles) {
        double area = 0;
        for (Rectangle rectangle : rectangles) {
            area += rectangle.width * rectangle.height;
        }
        return area;
    }
}
// Exemplo após aplicar o OCP
interface Forma {
    double calculateArea();
}
class Rectangle implements Forma {
    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 AreaCalculator {
    public double calculateArea(Forma [] formas) {
        double area = 0;
        for (Forma formas: formas) {
            area += forma.calculateArea();
        }
        return area;
    }
}

在第二個範例中,最初 AreaCalculator 類別直接依賴 Rectangle 類別。這表示如果您想要新增其他類型的形狀,例如圓形或三角形,則需要修改 AreaCalculator 類,從而違反 OCP。透過建立 Shape 接口,AreaCalculator 類別能夠在不修改現有程式碼的情況下接收新的幾何形狀。

3.里氏替換原理

里氏替換原則(LSP)規定超類別的物件必須可以被其子類別的物件替換,而不影響系統的完整性。換句話說,子類別的行為必須與超類別的行為一致。

// Classe base
class Bird {
    public void fly() {
        // Método padrão que imprime "Flying"
        System.out.println("Flying");
    }
}

// Classe derivada que viola o LSP
class Duck extends Bird {
    @Override
    public void fly() {
        // Sobrescrita que imprime "Ducks cannot fly"
        System.out.println("Ducks cannot fly");
    }
}

問題:Duck 類別重寫了 Fly() 方法來列印“鴨子不能飛”,因此我們更改了 Bird 基底類別中定義的預設行為,即所有鳥都會飛(“Flying”)。這違反了 LSP,因為任何期望 Bird 物件或其子類會飛的程式碼都無法與 Duck 一起正常工作,而我們已經知道 Duck 不會飛。

// Classe derivada que respeita o LSP
interface Bird {
    void fly();
}
class Eagle implements Bird {
    @Override
    public void fly() {
        System.out.println("Flying like an Eagle");
    }
}
class Duck implements Bird {
    @Override
    public void fly() {
        throw new UnsupportedOperationException("Ducks cannot fly");
    }
}

透過這種方法,Eagle 和 Duck 可以在需要 Bird 的地方互換,而不會打破 Bird 介面設定的期望。 Duck 拋出的異常明確地傳達了鴨子不會飛的信息,而沒有以可能導致代碼中出現意外問題的方式修改超類的行為。

4. 介面隔離原則

介面隔離原則(ISP)建議類別的介面應該特定於使用它們的客戶端。這避免了需要實作客戶端未使用的方法的「胖」介面。

// Exemplo antes de aplicar o ISP
interface Worker {
    void work();
    void eat();
    void sleep();
}

class Programmer implements Worker {
    @Override
    public void work() {
        // Lógica específica para programar
    }
    @Override
    public void eat() {
        // Lógica para comer
    }
    @Override
    public void sleep() {
        // Lógica para dormir
    }
}
// Exemplo após aplicar o ISP
interface Worker {
    void work();
}
interface Eater {
    void eat();
}
interface Sleeper {
    void sleep();
}
class Programmer implements Worker, Eater, Sleeper {
    @Override
    public void work() {
        // Lógica específica para programar
    }
    @Override
    public void eat() {
        // Lógica para comer
    }
    @Override
    public void sleep() {
        // Lógica para dormir
    }
}

在範例中,我們將 Worker 介面拆分為更小的介面(Work、Eat、Sleep),以確保實現它們的類別僅具有它們必需的方法。這可以防止類別必須實現與它們不相關的方法,從而提高程式碼的清晰度和內聚性。

5. 依賴倒置原則

依賴倒置原則(DIP)建議高層模組(例如實現主要業務規則的業務或應用程式類)不應依賴低層模組(基礎設施類,例如存取外部資料和支援進階操作的服務)。兩者都必須依賴抽象。

// Exemplo antes de aplicar o DIP
class BackendDeveloper {
    public void writeJava() {
        // Lógica para escrever em Java
    }
}
class Project {
    private BackendDeveloper developer;

    public Project() {
        this.developer = new BackendDeveloper();
    }
    public void implement() {
        developer.writeJava();
    }
}
// Exemplo após aplicar o DIP
interface Developer {
    void develop();
}
class BackendDeveloper implements Developer {
    @Override
    public void develop() {
        // Lógica para escrever em Java
    }
}
class Project {
    private Developer developer;

    public Project(Developer developer) {
        this.developer = developer;
    }
    public void implement() {
        developer.develop();
    }
}

Project 類別現在依賴抽象(Developer)而不是具體實作(BackendDeveloper)。這允許不同類型的開發人員(例如 FrontendDeveloper、MobileDeveloper)輕鬆注入 Project 類,而無需修改其程式碼。

結論

採用 SOLID 原則不僅可以提高程式碼質量,還可以增強您的技術技能,提高工作效率,並促進您作為軟體開發人員的職業道路。

以上是實體導向的開發的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn