.NET ヘルプ

Solid原則 C#(開発者にとっての仕組み)

更新済み 12月 12, 2023
共有:

SOLID 原則とは、これに従うことで堅牢で保守可能なソフトウェアエンティティを作成できる5つの設計原則のことです。 ロバート・C マーティンはこれらの原則を導入し、オブジェクト指向設計の基礎となりました。 C#とは、マイクロソフトによって開発された人気のオブジェクト指向プログラミング言語であり、SOLID原則を理解し適用することでコードの品質を大幅に向上させることができます。

この記事では、次の詳細なレビューを行います C#におけるSOLID原則 それらの用途について説明し、C# PDFライブラリを使用してPDFドキュメントを作成することによって再利用可能なコード構造をどのように書くことができるかも確認します。 IronPDF.

C#のSOLID原則の5つ

Solid原則 C#(開発者にとっての仕組み)図1

1.1. 単一責任の原則 (SRP)

単一責任の原則は、クラスは変更する理由が一つだけであるべきであり、つまり一つの責任のみを持つべきであると述べています。 C#では、この原則は開発者に特定のタスクに焦点を当てたクラスを作成することを奨励します。 例えば、ファイル操作を管理するクラスがデータベース接続も管理すべきではありません。

SOLID原則 C# (開発者向けの仕組み) 図2

1.2. オープン/クローズド原則 (OCP)

オープン/クローズド原則は、クラスは拡張には開放されているべきだが、変更には閉鎖されているべきだと提案しています。つまり、モジュールのソースコードを変更せずにその動作を拡張できるようにするということです。 C# では、これはしばしばインターフェイスや抽象クラスを通じて達成され、既存の契約に従う新しいクラスを作成することが可能になります。

C#のSOLID原則(開発者にとっての動作原理)図3

1.3. リスコフの置換原則 (LSP)

リスコフの置換原則は、スーパークラスのオブジェクトをサブクラスのオブジェクトで置き換えても、プログラムの正当性に影響を及ぼさないことを強調しています。 C#では、この原則はポリモーフィズムを奨励し、派生クラスが基底クラスと互換的に使用できるようにします。

SOLID原則C#(開発者のための仕組み)図4

インターフェース分離の原則 (ISP)

インターフェース分離の原則は、大きく一般的なインターフェースを使用するのではなく、小さく具体的なインターフェースを使用することを提唱します。 C#では、この原則により、実装クラスが必要としない機能を提供するよう強制する「ファット」インターフェイスの作成が推奨されません。 代わりに、それは特定のニーズに合わせた複数の小さなインターフェースを使用することを推奨します。

開発者向けのSolid原則 C#(開発者のための仕組み)図5

1.5. 依存関係逆転の原則 (DIP (デジタル画像処理))

依存関係逆転の原則は、高水準モジュールが低水準モジュールに依存するべきではなく、両方とも抽象クラスに依存するべきであるという考えを推進します。 C#では、依存性注入を使用して従来の制御フローを逆転させ、柔軟でテスト可能なコードを実現することが多いです。

開発者向けのSOLID原則C#(それがどのように機能するか)図6

SOLID設計原則の用途

SOLID原則は、クリーンで保守しやすいコードを設計するためのロードマップを提供します。 それらをどんな状況でも盲目的に従うべきではなく、特定のアプリケーションの文脈に基づいて慎重に適用するべきです。

単一責任の原則 (SRP)

シングル・リスポンシビリティ・プリンシプル(単一責任の原則)は、C#アプリケーションのクラス設計で有益です。 各クラスが単一の責任を持つことを保証することで、コードがよりモジュール化され、理解しやすくなります。 このモジュール性は保守に有益であり、コードベース全体に影響を与えることなく新機能の追加やバグの修正を簡単にします。

2.2. オープン/クローズド原則(OCP)

オープン/クローズド原則は、コードを変更せずに拡張する必要があるときに適用されます。 インターフェースと抽象クラスを使用することで、C#の開発者は既存のコードを変更せずに適応可能なシステムを作成できます。

2.3. リスコフの置換原則 (LSP)

リスコフの置換原則は、派生クラスが基本クラスの代わりとしてシームレスに使用できることを保証し、柔軟でスケーラブルなコードベースを促進します。 ポリモーフィズムが重要な場合、リスコフの置換原則を適用することが特に重要です。

2.4. インターフェース分離の原則 (ISP)

インターフェース分離の原則は、それを実装するクラスのニーズに合わせた小さく具体的なインターフェースを作成することを奨励します。 このアプローチはクラスに不必要なメソッドを強制することを防ぎ、より効率的で保守しやすい設計を促進します。

2.5. 依存性逆転の原則 (DIP (デジタル画像処理))

依存性反転の原則は、依存性注入を通じて、C#アプリケーションにおける疎結合コンポーネントの作成を容易にします。 この原則を実装することで、コード全体の複雑さが軽減され、そのテスト容易性が向上します。

2.6. 例

using System;
public abstract class Shape
{
    public abstract double Area();
}
class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area() => Math.PI * Math.Pow(Radius, 2);
}
class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public override double Area() => Width * Height;
}
class AreaCalculator
{
    public double CalculateArea(Shape shape) => shape.Area();
}
interface ILogger 
{
    void Log(string message); // interface segregation principle d
}
class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"Log: {message}");
}
class FileLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"File Log: {message}");
}
class UserService
{
    private readonly ILogger logger;
    public UserService(ILogger logger) => this.logger = logger;
    public void CreateUser()
    {
        logger.Log("User created successfully");
    }
}
class EmailService
{
    private readonly ILogger logger;
    public EmailService(ILogger logger) => this.logger = logger;
    public void SendEmail()
    {
        logger.Log("Email sent successfully");
    }
}
using System;
public abstract class Shape
{
    public abstract double Area();
}
class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area() => Math.PI * Math.Pow(Radius, 2);
}
class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public override double Area() => Width * Height;
}
class AreaCalculator
{
    public double CalculateArea(Shape shape) => shape.Area();
}
interface ILogger 
{
    void Log(string message); // interface segregation principle d
}
class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"Log: {message}");
}
class FileLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"File Log: {message}");
}
class UserService
{
    private readonly ILogger logger;
    public UserService(ILogger logger) => this.logger = logger;
    public void CreateUser()
    {
        logger.Log("User created successfully");
    }
}
class EmailService
{
    private readonly ILogger logger;
    public EmailService(ILogger logger) => this.logger = logger;
    public void SendEmail()
    {
        logger.Log("Email sent successfully");
    }
}
Imports System
Public MustInherit Class Shape
	Public MustOverride Function Area() As Double
End Class
Friend Class Circle
	Inherits Shape

	Public Property Radius() As Double
	Public Overrides Function Area() As Double
		Return Math.PI * Math.Pow(Radius, 2)
	End Function
End Class
Friend Class Rectangle
	Inherits Shape

	Public Property Width() As Double
	Public Property Height() As Double
	Public Overrides Function Area() As Double
		Return Width * Height
	End Function
End Class
Friend Class AreaCalculator
	Public Function CalculateArea(ByVal shape As Shape) As Double
		Return shape.Area()
	End Function
End Class
Friend Interface ILogger
	Sub Log(ByVal message As String) ' interface segregation principle d
End Interface
Friend Class ConsoleLogger
	Implements ILogger

	Public Sub Log(ByVal message As String) Implements ILogger.Log
		Console.WriteLine($"Log: {message}")
	End Sub
End Class
Friend Class FileLogger
	Implements ILogger

	Public Sub Log(ByVal message As String) Implements ILogger.Log
		Console.WriteLine($"File Log: {message}")
	End Sub
End Class
Friend Class UserService
	Private ReadOnly logger As ILogger
	Public Sub New(ByVal logger As ILogger)
		Me.logger = logger
	End Sub
	Public Sub CreateUser()
		logger.Log("User created successfully")
	End Sub
End Class
Friend Class EmailService
	Private ReadOnly logger As ILogger
	Public Sub New(ByVal logger As ILogger)
		Me.logger = logger
	End Sub
	Public Sub SendEmail()
		logger.Log("Email sent successfully")
	End Sub
End Class
VB   C#

このコードスニペットでは、オブジェクト指向プログラミングの明確な応用例があります。 (オブジェクト指向プログラミング (OOP)) 原則、特にSOLID原則が明らかです。 Shapeクラスは抽象基底クラスとして機能し、形状の共通の概念を定義し、抽象メソッドAreaを宣言します。(). 「子クラス」または「派生クラス」という用語は、共通の親クラスから継承するCircleクラスとRectangleクラスを指します。 両方のCircleとRectangleは派生クラスとして機能し、抽象基底クラスの機能を拡張して、面積の具体的な実装を提供します。() メソッド。 さらに、このコードは単一責任の原則など、SOLIDの原則を具体化しています。 (SRP)各クラスが明確な責任を持ち、依存性逆転の原則 (DIP (デジタル画像処理))ILoggerインターフェースの使用に示されているように、柔軟性と保守性を促進します。

3. IronPDFでSOLID原則を適用する

理論でSOLID原則を探求したので、次にIronPDFを使用してC#での実践的な応用に取り組んでみましょう。IronPDFは、PDFを扱うための人気ライブラリです。 IronPDFは、開発者がC#でPDFドキュメントをシームレスに作成、操作、および処理することを可能にします。 SOLID原則を統合することによって、コードをモジュール化しやすく、拡張性があり、保守可能な状態に保つことができます。

単一責任の原則を考慮する。 IronPDFを使用する際、PDFの生成や操作の特定の側面を処理するクラスを持つことは、有益です。 例えば、あるクラスはPDF文書を作成する一方で、別のクラスはコンテンツの追加とフォーマットに焦点を当てることができます。

オープン/クローズド原則は、拡張性を念頭に置いてPDF関連のクラスを設計することを推奨します。 既存のクラスを修正して新機能に対応させる代わりに、既存のインターフェースを継承または実装するクラスを作成することができます。 このようにして、既存の機能を損なうことなく原則を遵守します。

リスコフの置換原則は、異なる種類のPDF要素を扱う際に関与します。 テキスト、画像、注釈のいずれであっても、共通のインターフェースに準拠したクラスを設計することで、シームレスな置き換えが可能になり、PDF生成コードの柔軟性が向上します。 IronPDFと相互作用するクラスの契約を定義する際には、インターフェース分離の原則が重要です。 異なるコンポーネントのニーズに合わせた、小さく特定のインターフェースを作成することにより、不必要な依存関係を回避し、クラスが必要とするメソッドのみを実装することを確保します。

最後に、依存関係逆転の原則を適用することで、コードのテスタビリティと保守性を向上させることができます。 依存関係をハードコーディングするのではなく注入することにより、更新や拡張が容易なより疎結合のシステムを作成します。

以下に、IronPDFを使用した簡単なコード例を用いてこれらの概念を説明します:

using IronPdf;
using System;
// Interface for PDF creation
public interface IPdfCreator
{
    void CreatePdf(string filePath,string content);
}
// Concrete implementation using IronPDF
public class IronPdfCreator : IPdfCreator
{    
    public void CreatePdf(string filePath,string content)
    {        // IronPDF-specific code for creating a PDF
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(content);
        pdf.SaveAs(filePath);
    }
}
// Service adhering to Single Responsibility Principle
public class PdfGenerationService
{
    private readonly IPdfCreator pdfCreator;
    public PdfGenerationService(IPdfCreator pdfCreator)
    {
        this.pdfCreator = pdfCreator;
    }
    public void GeneratePdfDocument(string filePath)
    {
        // Business logic for generating content
        string content = "<p>This PDF is generated using IronPDF and follows SOLID principles.</p>";
        // Delegate the PDF creation to the injected dependency
        pdfCreator.CreatePdf(filePath,content);
        Console.WriteLine($"PDF generated successfully at {filePath}");
    }
}
class Program
{
    static void Main()
    {
        // Dependency injection using the Dependency Inversion Principle
        IPdfCreator ironPdfCreator = new IronPdfCreator();
        PdfGenerationService pdfService = new PdfGenerationService(ironPdfCreator);
        // Generate PDF using the service
        string pdfFilePath = "output.pdf";
        pdfService.GeneratePdfDocument(pdfFilePath);
        Console.ReadLine(); // To prevent the console window from closing immediately
    }
}
using IronPdf;
using System;
// Interface for PDF creation
public interface IPdfCreator
{
    void CreatePdf(string filePath,string content);
}
// Concrete implementation using IronPDF
public class IronPdfCreator : IPdfCreator
{    
    public void CreatePdf(string filePath,string content)
    {        // IronPDF-specific code for creating a PDF
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(content);
        pdf.SaveAs(filePath);
    }
}
// Service adhering to Single Responsibility Principle
public class PdfGenerationService
{
    private readonly IPdfCreator pdfCreator;
    public PdfGenerationService(IPdfCreator pdfCreator)
    {
        this.pdfCreator = pdfCreator;
    }
    public void GeneratePdfDocument(string filePath)
    {
        // Business logic for generating content
        string content = "<p>This PDF is generated using IronPDF and follows SOLID principles.</p>";
        // Delegate the PDF creation to the injected dependency
        pdfCreator.CreatePdf(filePath,content);
        Console.WriteLine($"PDF generated successfully at {filePath}");
    }
}
class Program
{
    static void Main()
    {
        // Dependency injection using the Dependency Inversion Principle
        IPdfCreator ironPdfCreator = new IronPdfCreator();
        PdfGenerationService pdfService = new PdfGenerationService(ironPdfCreator);
        // Generate PDF using the service
        string pdfFilePath = "output.pdf";
        pdfService.GeneratePdfDocument(pdfFilePath);
        Console.ReadLine(); // To prevent the console window from closing immediately
    }
}
Imports IronPdf
Imports System
' Interface for PDF creation
Public Interface IPdfCreator
	Sub CreatePdf(ByVal filePath As String, ByVal content As String)
End Interface
' Concrete implementation using IronPDF
Public Class IronPdfCreator
	Implements IPdfCreator

	Public Sub CreatePdf(ByVal filePath As String, ByVal content As String) Implements IPdfCreator.CreatePdf ' IronPDF-specific code for creating a PDF
		Dim renderer = New ChromePdfRenderer()
		Dim pdf = renderer.RenderHtmlAsPdf(content)
		pdf.SaveAs(filePath)
	End Sub
End Class
' Service adhering to Single Responsibility Principle
Public Class PdfGenerationService
	Private ReadOnly pdfCreator As IPdfCreator
	Public Sub New(ByVal pdfCreator As IPdfCreator)
		Me.pdfCreator = pdfCreator
	End Sub
	Public Sub GeneratePdfDocument(ByVal filePath As String)
		' Business logic for generating content
		Dim content As String = "<p>This PDF is generated using IronPDF and follows SOLID principles.</p>"
		' Delegate the PDF creation to the injected dependency
		pdfCreator.CreatePdf(filePath,content)
		Console.WriteLine($"PDF generated successfully at {filePath}")
	End Sub
End Class
Friend Class Program
	Shared Sub Main()
		' Dependency injection using the Dependency Inversion Principle
		Dim ironPdfCreator As IPdfCreator = New IronPdfCreator()
		Dim pdfService As New PdfGenerationService(ironPdfCreator)
		' Generate PDF using the service
		Dim pdfFilePath As String = "output.pdf"
		pdfService.GeneratePdfDocument(pdfFilePath)
		Console.ReadLine() ' To prevent the console window from closing immediately
	End Sub
End Class
VB   C#
  1. IPdfCreator インターフェース: 単一責任の原則に従い、一つの責任に集中することでPDF作成の契約を定義します。

  2. IronPdfCreator クラス: IronPDF を使用して PDF を作成する IPdfCreator を実装します。 このクラスは、PDF作成に特有のロジックをカプセル化します。

  3. PdfGenerationServiceクラス: PDFの生成を担当するサービスを表します。 それは、コンテンツ生成のビジネスロジックを処理し、PDF作成を注入された IPdfCreator に委任することで、単一責任の原則に準拠しています。

    1. **プログラムクラス (メイン)次の内容を日本語に翻訳してください:

:** サービスと注入された依存関係の使用を示し、抽象に依存することで依存関係逆転の原則を遵守します (インターフェース) 具体的な実装よりも。

このコードを実行するには、プロジェクトにIronPDFライブラリをインストールしてください。 これを NuGet パッケージ マネージャーを使用して行うことができます。

Install-Package IronPdf

以下のクラス PdfGenerationService の内容とロジックをお客様の特定の要件に置き換えてください。

3.1. 出力

SOLID原則 C#(開発者向けの仕組み)図7

結論

結論として、SOLID原則は、C#で保守可能かつスケーラブルなソフトウェアを設計するための堅固な基盤を提供します。 これらの原則を理解して適用することにより、開発者は変更に適応しやすく、テストしやすいよりモジュール化されたコードを作成できます。

IronPDFなどのライブラリを使用する際には、SOLID原則を統合することがさらに重要になります。 これらの原則に従ったクラスを設計することは、PDF関連のタスクの変化する要件に対応できる柔軟なコードを維持するために重要です。

C#アプリケーションの開発を進める中で、時の試練に耐えるコードを作成するための指針として、SOLID原則を念頭に置いてください。PDF生成、データベースとのやり取り、または他のソフトウェア開発の側面に取り組む場合であっても、SOLID原則は長期的に機能的で保守可能なコードを構築するためのロードマップを提供します。

詳細についてはIronPDFライブラリ、訪問これ. ライセンスについて学び、無料トライアルを取得するには、こちらを訪問してください これ.

< 以前
C# スイッチステートメント (開発者向けの仕組み)
次へ >
C# Json シリアライザー(開発者向けの動作)

準備はできましたか? バージョン: 2024.9 新発売

無料のNuGetダウンロード 総ダウンロード数: 10,659,073 View Licenses >