オブジェクト向け設計の5原則


4ヶ月くらい前かな...
ケイン(仮名)に聞いたことがある.
「MSAアーキテクチャをよりよく維持するにはどうすればいいか分かりません.記事に関連するすべてのAPIをRider Controllerに置くべきですか?」
一人が返事をした.
一つのクラスでやったことは一つしかないほうがいい.SPRって知ってる? 単一責任の原則
知っているのに、思い出せない…
~「勉強をおろそかにして…」 という思いが閃き、本を開けてみると…

SOLIDとは?



固体.

実船
いいえ...おっさん風冗談
プログラミングでは,SOLIDとはオブジェクト向け設計の5原則を指す.
  • 単一責任原則(SPR):単一責任原則
  • オープン原則:
  • LSP:リスク交換の原則
  • インターフェース集約原則:インターフェース分離原則
  • DIP:依存逆転原則
  • 五原則の前の字から取って、S O L I Dと言います.
    これは、開発者がソフトウェアのメンテナンスと拡張を簡素化するために約束したものです.

    単一責任原則(a.k.a SRP)


    「各レベルは1つのみ」
    すべてのクラス(モジュール、関数...)1つの責任しかありません.クラスを変更する理由は1つしかありません.その責任は一緒にカプセル化されます.
    クラスに2つ以上の責任がある場合、後でクラスを変更する際に確認する必要がある事項が多くなり、エッジ異常のリスクも増加します.つまり、メンテナンスが難しくなる確率が高い.
    public class Sex{
        final static Boolean isFemale = true;
        final static Boolean isMale = false;
    
        void printSex(){
        	if(this.isFemale){
            	System.out.println("여자");
            } else {
            	System.out.println("남자");
            }
        }
    }
    例えば、このprintSexという方法はSRPに違反していると言える.彼女はすべての女性と男を体現したいからだ.メソッドがif文を用いて分岐処理を行う場合、単一の責任原則を遵守しない可能性が高い.この方法はこのような異なる実装を実現することができる.
    public abstract class Sex{
    	abstract void printSex();
    }
    
    public class Female extends Sex{
    	void printSex(){
        	System.out.println("여자");
        }
    }
    
    public class Male extends Sex{
    	void printSex(){
        	System.out.println("남자");
        }
    }
    オブジェクト向けの4つのプロパティ  モデリングプロセスを担当する抽象的な関係と最も密接です.

    オープンクローズの原則(A.K.A OCP)


    「拡張はオープンでなければなりません.境界は閉鎖でなければなりません.」
    プログラムの既存の機能は拡張可能ですが、一度に作成したコードを変更する必要はありません.これは、コードを変更することなく機能を拡張できることを意味します.
    例題と一緒に整理するのは簡単そうです.
    public boolean purchase(Object card, String name, int price)
    {
        boolean result;
        
        switch (card.toUpperCase())
        {
            case "A" -> result = ((CardA) card).send(price);
            case "B" -> result = ((CardB) card).send(price);
            case "C" -> result = ((CardC) card).send(price);
            
            default -> {
                System.out.println("유효하지 않은 카드사");
                result = false;
            }
        }
        
        return result;
    }
    public boolean purchase(Purchasable purchasable, int price)
    {
        return purchasable.send(price);
    }
    
    instanceofのようなタイプの確認演算子を使用すると、このコードはオープンクローズの原則を守らない可能性があります.
    継承構造をどのように記述し、抽象メンバー(メソッド、属性)として使用するかが開発者の責任です.未来の変化を予測し、抽象化しなければならない.予測が多すぎるからといって抽象的ではなく、何も拡張できないためにすべてを閉じて隠すこともできない.いい加減にしろ.(コードhttps://blog.itcode.dev/posts/2021/08/14/open-closed-principle.htmlを参照)

    リスコフ交換の原則(a.k.a LSP)


    「サブタイプは常にベースタイプに置き換える必要があります.」
    すなわち、子クラスのインスタンスは、親クラスのインスタンスとして機能するために、親オブジェクト参照変数と一致する必要があります.これはOOPの4つの特性の継承であり,インタフェースの原則がよく守られている限り,LSPは良い応用である.
    携帯電話の音量上昇ボタンは、音声を増幅する機能があり、携帯電話の電源を切るとLSP違反とみなされます.

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


    「1つの汎用インタフェースよりも、複数の特定のインタフェースの方が優れています.」
    ISPの原理は,クラスが自分が使用しないインタフェースを実現すべきではないということである.つまり、あるクラスが別のクラスに属している場合、できるだけ少ないインタフェースを使用する必要があります.
    SRPがクラスの単一責任を強調する場合、ISPはインタフェースの単一責任を強調する.ただし、ISPは、あるクラスまたはインタフェースに複数の責任または役割があることを認めます.SRPはクラス分離によって変化に適応し,ISPはインタフェース分離によって同じ目標を達成する.
    例えば、iphoneを作成するとします.
    アップルMAX、アップルMAXPRO、アップルMINIが作られていますが、すべての機能はiPhoneというインタフェースに置いてありますよね?
    すべてのIPHONEシリーズのインタフェースに適用されます.
    interface IPhone {
        String telephone();
    
        String internet();
        
        String photo();
        
    }
    IPHONE 13シリーズのインタフェースにのみ適用されます.
    interface IPhone13 extends IPhone {
        String HDR4(); //13부터 HDR4로 바꼈으니 해당 기능을 넣어보겠다.
        
    }
    IPHONE 13 Proのインタフェースにのみ適用されます.
    interface IPhone13Pro extends IPhone, IPhone13  {
    	String Promotion();// 뭔지 모르겠지만 13 기능 중에 pro만 추가되었다고 해서..    
    }
    Override.. 作者は体力低下で省略
    class IPhone13Pro implements IPhone13Pro  {
    	
        @Override
        ~~~~~~~~생략
    }

    依存逆転原則(a.k.a DIP)


    「抽象に頼るには、具体化に頼るわけにはいかない」.
    高レベルモジュールは、低レベルモジュールの実装に依存することはできない.
    低レベルモジュールは、高レベルモジュールで定義された抽象タイプに依存する必要があります.
    サブモジュールは、親モジュール定義の抽象タイプ(インタフェース)に依存する必要があります.
    つまり、自分より変わりやすいものに頼ってはいけません.
    新しく買ったズボンが大きすぎて、太ってしまいます.他の服は合わないかもしれません.

    リファレンス


    https://ko.wikipedia.org/wiki/%EB%A6%AC%EC%8A%A4%EC%BD%94%ED%94%84_%EC%B9%98%ED%99%98_%EC%9B%90%EC%B9%99
    https://dahye-jeong.gitbook.io/java/java/2020-03-21-solid
    https://www.nextree.co.kr/p6960/
    https://wooaoe.tistory.com/57
    https://sjh836.tistory.com/159