SOLID指向の開発

Jul 24, 2024 pm 04:37 PM

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 サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? Apr 19, 2025 pm 11:27 PM

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

See all articles