オブジェクト指向プログラミングのための立体原理を学ぶ


オブジェクト指向プログラミング(OOP)は、オブジェクトとして知られているモデルにデータと行動をカプセル化するプログラミングのスタイルです.このように、関連コードは一緒に集められて、他のコードから分離しておいて、手で問題を合理化するのに用いられることができる再利用可能なブロックを提供します.
OOPはおそらく最も一般的な形式のプログラミングの1つであり、多くの一般的なプログラミング言語は、C - Chorz、Java、およびJavaScriptを含む、これを念頭に構築されています.
多くの言語で、オブジェクトのための青写真は、クラスとして知られています.クラスは、プロパティと関数(より一般的にメソッドとして知られている)を含む、そのオブジェクトのすべての定義を含みます.
実際のオブジェクトを作成するには、すべてのプロパティ定義に実際の値が与えられるクラスのインスタンスを作成します.重要なことは、同じクラスの複数のインスタンスを同時に持つことができます.
たとえば、NameプロパティとSpeakメソッドを持つ単純なPersonクラスを作成できます.
public class Person
{
    public Person(string name)
    {
        Name = name;
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public void Speak()
    {
        Console.WriteLine($"My name is {Name}");
    }
}
これは青写真です.現在、クラスの2つの別々のインスタンスを作成することができ、それぞれの実際のオブジェクトがNameプロパティの異なる値でインスタンス化されるので、Speakメソッドは異なる出力を行います.
var bernard = new Person("Bernard");
var sally = new Person("Sally");

bernard.Speak(); // outputs "My name is Bernard"
sally.Speak(); // outputs "My name is Sally"
これらは非常に簡単な例ですが、うまくいけば、これらのオブジェクトの青写真を作成し、実際のオブジェクトの別のインスタンスを作成できることの利点を見ることができます.
しかし、あなたが注意しないならば、それは誤用オブジェクトに簡単でありえて、読むのが難しいか不安定なコードをつくることができます.たとえば、同じオブジェクトに詰め込まれた無関係な振る舞いがたくさんある「God」クラスが潜在的に終わる可能性があります.
良い、保守可能な、安定したコードを書くのを助けるために、しっかりした原則は以下で説明されました.

  • 単一責任原則

  • oオープン/クローズド原理

  • Lskov置換原理

  • 界面分離原理

  • 依存性反転原理
  • 単一責任原則


    ここのタイトルはかなり自己説明です.クラスは1つの責任を持つべきです.これは“God”クラスのシナリオを避けるためです.クラスがすべてを実行し、コードを小さく、分別のあるチャンクに分割するのに役立ちます.
    単一の責任原則は、非常に理解しやすいですが、実際には、それは常に簡単なときに何かがクラスに属しているときに別のクラスに移動する必要がありますスポットすることはありません.この判断を行うことはほとんど経験の問題であり、あなたはそれを時間とともに良くなるでしょう.
    我々が我々の人クラスに戻るならば、我々は我々が各々の人をデータベースに保存したいと決めるかもしれません.したがって、Personクラスでメソッドを作成するのは賢明かもしれません.
    public class Person
    {
        // ... other properties and methods
    
        public void SaveToDatabase()
        {
            // logic to save person
        }
    }
    
    しかしながら、ここでの問題は、人をデータベースに保存する方法の詳細は追加の責任であり、責任は別のクラスに移されるべきです.
    したがって、SavePersonメソッドを使用してデータベースクラスを作成し、そのクラスにそのインスタンスを渡すことができます.その人のクラスだけが人の詳細に対処し、データベースクラスは人を救うの詳細に対処します.
    public class Database 
    {
        public void SavePerson(Person person)
        {
            // logic to save person
        }
    }
    

    oオープン/クローズド原理


    開いた/閉じられた原則は、オブジェクトが拡張のために開いていなければならなくて、変更のために閉じられるべきであると述べます.これは、オブジェクトを直接変更することなく簡単に拡張できるようなオブジェクトをデザインする必要があることを意味します.
    例えば、Personクラスから派生した従業員とマネージャーの2つの新しいクラス、およびSalaryCalculatorクラスを定義できます.
    public class Employee : Person
    {
        // employee methods and properties
    }
    
    public class Manager : Person
    {
        // manager methods and properties
    }
    
    public class SalaryCalculator
    {
        public decimal CalculateSalary(Person person)
        {
            if (person is Employee)
            {
                return 100 * 365;
            }
            else if (person is Manager)
            {
                return 200 * 365;
            }
        }
    }
    
    この例では、SalaryCalculatorクラスは、Operationクラスを追加することによってプログラムを拡張する場合は、CalculateSeararyメソッドを変更する必要があります.
    これを修正するには、それぞれの型にDailyRateプロパティを追加できます.そのように、我々は多くの人として我々が望むように追加することができますsalary電卓を変更する必要はありません.
    public class Person
    {
        public virtual decimal DailyRate => 0;
    }
    
    public class Employee : Person
    {
        public override decimal DailyRate => 100;
    }
    
    public class Manager : Person
    {
        public override decimal DailyRate => 200;
    }
    
    public class Director : Person
    {
        public override decimal DailyRate => 300;
    }
    
    public class SalaryCalculator
    {
        public decimal CalculateSalary(Person person)
        {
            return person.DailyRate * 365;
        }
    }
    

    Lskov置換原理


    Liskov代用原理は、すべてのサブクラスが基底クラスのために代わるべきであると述べます、そして、プログラムはまだ予想通りふるまうでしょう.
    開/閉原理の例はliskov置換原理の良い例でもある.
    SalaryCalculatorクラスでは、メソッドは基本クラスのPersonを受け取りますが、実行時にサブクラスのどれかを渡すこともできます.私たちは、人と下位クラスの仮想キーワードとオーバーライドのキーワードをそれぞれ使用しているので、CalculateScalaryメソッド内のDailyRateの値は、サブクラスクラスのサブクラスです.
    Liskovの代用原理を破る例として、クラスを再定義することができます.
    public class Person 
    {
        public decimal DailyRate => 0;
    }
    
    public class Employee
    {
        public new() decimal DailyRate => 100;
    }
    
    この定義を使用すると、DailyRateは常にSalaryCalculatorで0に評価され、サブクラスの値ではないため、Liskov代用原理に違反します.

    界面分離原理


    インタフェース分離原則は、クライアントが使用しないインターフェイスのプロパティとメソッドを実装することを強制されるべきではないことを示します.したがって、少数の大きな、一般的なインターフェースではなく、多くの小さな、特定のインターフェースを定義する方がよいです.
    例として、データベース上のPersonクラスのCRUD操作を実行するためのIRepositoryインターフェイスを定義し、実装します.
    public interface IRepository
    {
        bool Create(Person person);
        Person Get(int id);
        IEnumerable<Person> GetAll();
        bool Update(Person person);
        bool Delete(int id);
    }
    
    public class Repository : IRepository
    {
        public bool Create(Person person)
        {
            // create logic
        }
    
        public Person Get(int id)
        {
            // get logic
        }
    
        // etc
    }
    
    我々が常に完全なcrud機能を必要とするということを知っているならば、これはすばらしいです.しかし、実際には、リポジトリを読み込み専用にするだけですか?すぐに、私たちは完全なCRUD操作を実装することを強制されます.
    代わりに、複数のインターフェイスを定義することができます.
    public interface ICreatableRepository
    {
        bool Create(Person person);
    }
    
    public interface IGettableRepository
    {
        Person Get(int id);
        Person GetAll();
    }
    
    public interface IUpdateableRepository
    {
        bool Update(Person person);
    }
    
    public interface IDeletableRepository
    {
        bool Delete(int id);
    }
    
    次に、任意のオプションを実行するReadOnlyリポジトリまたは完全なCRUDリポジトリを選択することができます.
    public class ReadonlyRepository : IGettableRepository
    {
        public Person Get(int id)
        {
            // get logic
        }
    
        public IEnumerable<Person> GetAll()
        {
            // get all logic
        }
    }
    
    public class CrudRepository : ICreateableRepository, IGettableRepository, IUpdateableRepository, IDeleteableRepository
    {
        public bool Create(Person person)
        {
            // create logic
        }
    
        public Person Get(int id)
        {
            // get logic
        }
    
        // etc
    }
    

    依存性反転原理


    依存関係の反転原理は、クラスは他のクラスに依存してはいけませんが、代わりにそれらのクラスが実装するインターフェイスに依存するべきであると述べます.これは依存の方向を反転させる効果があります.
    たとえば、クラスだけで構成される伝統的な3層アプリケーションはPersonPresenterクラスを持っているかもしれません.PersonPresenterクラスは、PersonLiveクラスに依存します.例えば
    PersonPresenter --> PersonLogic --> PersonRepository
    
    この問題は、ハイレベルのプレゼンテーションを低レベルの実装の詳細に厳密に結合することです.緩やかに結合されたコードを持っている方がずっと良いです.インターフェイスの使用の理由については、以前のブログ記事を参照ください.


    依存性を反転するには、それぞれの低レベルクラスのインターフェイスを作成し、クラスを実装します.
    PersonPresenter --> IPersonLogic <-- PersonLogic --> IPersonRepository <-- PersonRepository
    

    結論


    したがって、オブジェクト指向プログラミングの5つのしっかりした原則があります.あなたがそれが役に立つとわかるならば、好きにして、このポストを共有してください.そして、あなたが望むならば、私に続くのを自由に感じてくださいbuy me a coffee ! 😊