SOLID指向の開発

WBOY
リリース: 2024-07-24 16:37:00
オリジナル
708 人が閲覧しました

Desenvolvimento Orientado a SOLID

ソフトウェア開発では、コードのメンテナンス、拡張、柔軟性がプロジェクトの長期的な成功にとって重要です。 SOLID 原則は、開発者が理解しやすく、変更し、拡張しやすいコードを作成できるように策定されました。この記事では、SOLID の 5 つの原則のそれぞれについて、および Java での実際の例とともにその使用方法について説明します。

1. 単一責任の原則

単一責任原則 (SRP) は、クラスが変更する理由は 1 つだけである必要があること、つまり、クラスはシステム内で単一の責任を持つ必要があることを確立します。

// 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;
    }
}
ログイン後にコピー

この 2 番目の例では、当初、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 基本クラスで定義されているデフォルトの動作、つまりすべての鳥が飛ぶ (「飛ぶ」) を変更します。これは 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");
    }
}
ログイン後にコピー

このアプローチを使用すると、Bird インターフェースによって設定された期待を裏切ることなく、Bird が期待される場所で Eagle と Duck を交換できます。 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 クラスは、具体的な実装 (BackendDeveloper) ではなく抽象化 (Developer) に依存するようになりました。これにより、コードを変更せずに、さまざまなタイプの開発者 (FrontendDeveloper、MobileDeveloper など) を Project クラスに簡単に挿入できるようになります。

結論

SOLID 原則を採用すると、コードの品質が向上するだけでなく、技術スキルが強化され、作業効率が向上し、ソフトウェア開発者としてのキャリアパスも向上します。

以上がSOLID指向の開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート