オブジェクト向けデザイン5原則SOLIDを破壊せよ!


金英漢スプリングの核心原理の源


1.SRP単一責任原則


Single Resposibility Principle


「一つの階級には一つの責任しかない」.
「クラスを変更した理由は一つしかない」-ロバートC.マーティン
クライアント・オブジェクトは実行のみを担当します.ex) MemberServiceImpl外部注入依存性の役割は別途設けられている.ex) AppConfig
public class AppConfig {
    // AppConfig는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성한다.
    // 그리고 생성한 객체 인스턴스의 참조를 생성자를 통해서 주입해준다.(생성자 주입 방식)

    // 생성자 주입 방식
    // 리팩토링 중복부분 -> 메서드로 다른 구현체 만듦
    // 효과 : AppConfig을 보면 역할과 구현클래스가 한눈에 들어온다.
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    private MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    public DiscountPolicy discountPolicy() {
        return new FixDiscountPolicy();
    }
}

2.OCP開放閉鎖原則


Open Cloesd Principle


「ソフトウェア要素は拡張で開く必要がありますが、変更では閉じる必要があります(変更する必要はありません).
多形性を使用するには、クライアント・オブジェクトはDIPを遵守する必要があります.
実装インタフェースの新しいクラスを作成して新しい機能を実装しても、クラスを変更する必要はありません.

  • EX)JDBC:OracleからMySQLにデータベースが変更されても、接続の設定以外に変更する必要はありません.

  • オープン・クローズの原則を無視してプログラムを記述すると、柔軟性、再利用性、メンテナンス性など、オブジェクト向けのプログラミングの最大の利点は得られません.

  • 正直、対象原理の中で最も重要な核心原則に向かいます!
  • 3.LSPリスク交換の原則


    Liskov Substiution Principle


    「サブタイプは常に独自のベースタイプに置き換える必要があります.」ロバートC.マーティン
    多形性では、サブインプリメンテーションクラスはすべてのインタフェースの約束を守らなければならない.
    逆に、クラスは階層図ではなく分類図に従う必要があります.
  • ex)継承は組織でも階層(父-娘)でもなく、分類(ペンギン-シラサギ)です.
  • 4.ISPインタフェースを分離する原則


    Interface Segregation Principle


    「クライアントは使用しない方法に依存してはいけません.」ロバートC.マーティン
  • 自動車インタフェース->運転インタフェース、メンテナンスインタフェースから
  • 分離
  • ユーザークライアント->パイロットクライアント、メンテナンス担当クライアント
  • に分離
  • 離脱後、メンテナンスインターフェース自体が変化し、ドライバークライアント
  • に影響しない.
  • インタフェースは明確で、代替性が高い.
  • 5.DIP依存逆転の原則


    Dependency Inversion Principle


    「プログラマーは、具体化ではなく抽象(インタフェース)に頼るべきです.依存性注入は、この原則に従う方法の1つです.」
    これは、実装クラスに依存せず、インタフェースに依存することを意味する.
  • オブジェクト世界でも、実装体を柔軟に変更するには、クライアント依存インタフェースが必要です.
  • 実施形態に依存する場合、変更は非常に困難になるであろう.
  • // DIP , OCP 위반
    public class OrderServiceImpl implements OrderService{
    
        private final MemberRepository memberRepository;
        private final DiscountPolicy discountPolicy;
    
    // 의존성 주입, 여기서 정책을 바꿔 discountPolicy가 뭔지 알 필요없다. 외부에서 주입해주니까. 코드에 의존 x, 인터페이스만 의존
        public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
            this.memberRepository = memberRepository;
            this.discountPolicy = discountPolicy;
        }
    
        private final DiscountPolicy discountPolicy = new FixDiscountPolicy();    // OrderServiceImp가 구현클래스에 의존한다.
        private final DiscountPolicy discountPolicy = new RateDiscountPolicy();      // 정책이 바뀌어 코드까지 바뀐다. DIP 위반!
        // FixDiscountPolicy -> RateDiscountPolicy 변경은?
    
    
    ...
    }

    整理する


    キム・ヨンハンの基礎課程を通じて、インタフェースは役割(責任)と実現クラスを徹底的に分離しなければならないことが分かった.これはオブジェクト向けの核心だ.この意味では,オブジェクト指向の原理においてOCP,ISP,DIPが最も有意義であり,次いでSRP,LSPである.
    キム・ヨンハンの講義を通じて、難しい概念をうまく整理して、キム・ヨンハンが無駄にやったわけではないと思った.

    ソース


    https://github.com/mooh2jj/springcore1.git