[基本]スプリングのモノトーン


以前の位置付け



注文にはリポジトリと割引ポリシーが必要です.リポジトリと割引ポリシーは可変です.

  • 受注、リポジトリ、割引ポリシーを単純クラスに実装します.
  • 制限:リポジトリと割引ポリシーが変更された場合は、リポジトリと割引ポリシーオブジェクトを使用する受注クラスも変更する必要があります.

  • インタフェースは、リポジトリおよび割引ポリシーの親として使用され、インタフェースを参照変数とするオブジェクトを作成して使用します.(多形性利用)
  • MemberRepositoyとDiscountPolicyをインタフェースとする.
  • OrderServiceImplは、インタフェースを参照変数とするインスタンスを作成することによって、ビジネスロジックを実行する.
  • リポジトリと割引ポリシーを変更する場合は、受注にリポジトリと割引ポリシーインスタンスを作成するときにインプリメンテーションを置き換えるだけです.
  • 制限:リポジトリおよび割引ポリシーの実装が変更された場合、OrderServiceImplで作成されたオブジェクトの一部も変更する必要があります.

  • 受注のフィールドには、リポジトリと割引ポリシーの参照変数のみが保持され、作成者に受注を受け入れさせます.AppConfigを作成して、すべてのオブジェクトを作成します.
  • AppConfigリポジトリおよび割引ポリシーオブジェクトを作成します.2つのオブジェクトに注入された受注オブジェクトも生成されます.
  • リポジトリは、割引ポリシーの実施体が変更された場合、AppConfigでその部分を変更するだけです.
  • オブジェクトが必要な場合は、AppConfigメソッドを使用して作成できます.
  • オブジェクトを作成し、AppConfigを分離して依存性を注入します.OrderServiceでは、フィールドに存在するリポジトリと割引ポリシーを使用するだけです.
  • インタフェースとAppConfigの導入により、DIPを遵守できます.

    疑問点


    インタフェースを導入することで、作成と注入オブジェクトの設定クラスを分離し、受注がリポジトリと割引ポリシーオブジェクトのみを使用できるようにし、DIPの原則を遵守します.
    スプリングは設定クラスをパラメータとして受け入れ、スプリングコンテナ内にオブジェクトを作成します.これをスプリング空席と呼び、スプリングはこれらのオブジェクトを管理し、オブジェクトを使用するときにコンテナから取り出して使用する必要があります.
    コンフィグクラスからオブジェクトをインポートするだけで済むのに、なぜスプリングを導入してコンテナに登録、取り出し、使用しなければならないのでしょうか.

    モノトーン

    public class AppConfig {
    	
        //저장소 객체 생성
        public MemberRepository memberRepository() { 	
            return new MemoryMemberRepository();
        }
    	
        //할인정책 객체 생성
        public DiscountPolicy discountPolicy() { 
            return new RateDiscountPolicy();
        }
        
        //저장소와 할인정책객체 주입한 주문객체 생성
        public OrderService orderService() { 
            return new OrderServiceImpl(memberRepository(), discountPolicy());
        }
    
    }
    AppConfigは、オブジェクトを作成する方法を提供します.クライアントは、ここでオブジェクトを要求し、そのオブジェクトを受信して使用します.

    ここで問題が発生しました.
    Webはリクエストが非常に多い場所であり、リクエストごとに新しいオブジェクトが作成されると、オーバーヘッドが非常に大きくなります.AppConfigで生成されたオブジェクトをすべてのクライアントにモノトーンで渡すということでよろしいでしょうか?

    モノトーンに変更

    public class rateDiscountPolicy implements DiscountPolicy {
        //1. static 영역에 객체 1개 생성해둠
        private static final DiscountPolicy instance 
        		= new rateDiscountPolicy();
        
        //2. public으로 객체 인스턴스 필요시 static 메서드로 생성해둔 객체 반환하도록
        public static DiscountPolicy getInstance() {
        	return instance;
        }
     	
        // 3. 생성자를 private로 막아 추가 생성 못하도록
        private rateDiscountPolicy() {
        }
    }
    単一の色調を実現するには、オブジェクトを作成し、オブジェクトを返す方法を定義し、作成者をプライベート化する煩雑な修正が必要であり、柔軟性が劣っています.

    スプリングコンテナは、オブジェクトインスタンスをモノトーンで管理します.また、DIP OCP違反、privateジェネレータなど、柔軟性の悪い問題もすべて解決し、便利な機能を提供しています.
    スプリングを使用して、単色調和スプリング管理オブジェクトがもたらすメリットを利用します.

    @構成とモノトーン


    Springコンテナにインスタンスを登録します.これを用いて、単一の色調を実現することにした.
    //빈 등록
    @Configuration
    public class AppConfig {
    	
        @Bean
        public MemberRepository memberRepository() { 	
            return new MemoryMemberRepository();
        }
    	
        @Bean
        public DiscountPolicy discountPolicy() { 
            return new RateDiscountPolicy();
        }
        
        @Bean
        public OrderService orderService() { 
            return new OrderServiceImpl(memberRepository(), discountPolicy());
        }
    }
    
    //빈 꺼내 사용
    public class test{
    	
        @Test
        void configurationTest(){
          ApplicationContext ac 
                  = new AnnotationConfigApplicationContext(AppConfig.class);
    
          Memberservice memberService = ac.getBean("memberService", MemberService.class);
        }
    }
    構成クラス@構成
    オブジェクト作成方法で@bean
    コンフィグクラスをAnnotationConfigApplicationContextのパラメータに移動します.対応する設定情報が登録されている空のスプリングコンテナを返して使用します.空はすべて単一の色調でオブジェクトを生成します.
    疑問が生じる
    AppConfigを表示し、リポジトリと割引ポリシーを空に登録します.
    次に、受注で生成メソッドを呼び出して依存注入を行い、リポジトリと割引ポリシーを生成します.
    これで2つのオブジェクトが2つの単一の色調になると割れてしまうのではないでしょうか.

    スプリングは刃位置操作のCGIBで防止します.
    SpringはConfigクラスをspring beanとして登録し、それに基づいて他のbeanを登録します.この場合、作成したConfigクラスではなく継承した偽造Configクラスが空に登録されます.

    各bean生成関数がすでに存在する場合、「構成の調整」クラスは「バイト」操作に変更され、返されます.これにより、単一の色調の存在が保証される.
    Springプロファイルを@Configurationに設定し、パラメータとして空の登録を行います.空の場合、Springは変更されたConfigサブクラスを登録し、コンテナから取り出して返します.スプリングシートのモノトーンを保証します.

    モノトーンの注意点


    単一のトーンでオブジェクトを共有します.したがって、新しいオブジェクトを作成する必要はありませんが、共有フィールドのために問題が発生する可能性があります.
    public class OrderService {
    	private int price;
        
        public void order(String item, int price) {
        	System.out.println("item = " + item + "price = " + price);
            this.price = price; //여기가 문제
        }
        
        public int getPrice() {
        	return price;
        }
    }
    上記のOrderServiceオブジェクトがモノトーンで共有されているとします.
    お客様Aは1万元のものを注文しました->Order Service Priceは10000です.
    クライアントBは20000元を注文しました->OrderService Pirceは20000です.
    顧客A照会金額->現在のオーダーサービス価格20000が出力されました.
    すなわち、顧客が共有フィールドpriceを変更すると、Aは注文後にBから注文され、Bの金額で上書きされる.モノトーンは無状態に設計されていることに注意してください.
    モノトーン(スプリングシート)は、常に状態を維持しない無状態に設計されている.特にオブジェクトのフィールドには注意してください.
    この文章は、金英漢の「スプリングの核心原理−基本編」課程の内容と理解内容をまとめたものだ.
    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8