๐Ÿ“– [Spring] ๐Ÿ’ป ์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ - 2. ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ ์ดํ•ด 1,2

๐Ÿ’ป [Spring] ์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ - ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ ์ดํ•ด 1,2

์•ˆ๋…•ํ•˜์„ธ์š”. ๐Ÿ‘‹

์Šคํ”„๋ง์œผ๋กœ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ–ˆ์—ˆ๋Š”๋ฐ 

๋ฌธ๋“ ์Šคํ”„๋ง ์ž์ฒด ํ•ต์‹ฌ ์›๋ฆฌ์— ๋Œ€ํ•œ ๋ณต์Šต์ด ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊น€์˜ํ•œ๋‹˜์˜ ์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉฐ 

์Šคํ”„๋ง์„ ์™œ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€์™€

์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ์— ๋Œ€ํ•ด ํ•™์Šตํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. 

๋‘๋ฒˆ์งธ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. 

์ง์ ‘ ์ˆœ์ˆ˜ ์ž๋ฐ”๋งŒ์„ ์ด์šฉํ•ด ๊ฐ์ฒด ์ง€ํ–ฅ ์›๋ฆฌ๋ฅผ ์ ์šฉํ•ด ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ง์ ‘ ์‹ค์Šตํ•ด๋ณด๋ฉฐ ๋Š๋‚€ ์ฃผ์š” ๋‚ด์šฉ๋“ค์„ ์œ„์ฃผ๋กœ ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ์„œ๋ก 

์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์ดํ•ด ํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์ œ๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ ์ž๋ฐ”๋งŒ์„ ์ด์šฉํ•ด ๋‹ค์Œ์˜ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ฐ€์ง„ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ์„ค๊ณ„
- ํšŒ์›
    - ํšŒ์›์„ ๊ฐ€์ž…ํ•˜๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
    - ํšŒ์›์€ ์ผ๋ฐ˜๊ณผ VIP ๋‘ ๊ฐ€์ง€ ๋“ฑ๊ธ‰์ด ์žˆ๋‹ค.
    - ํšŒ์› ๋ฐ์ดํ„ฐ๋Š” ์ž์ฒด DB๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ณ , ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋ฏธํ™•์ •)
- ์ฃผ๋ฌธ๊ณผ ํ• ์ธ ์ •์ฑ…
    - ํšŒ์›์€ ์ƒํ’ˆ์„ ์ฃผ๋ฌธํ•  ์ˆ˜ ์žˆ๋‹ค.
    - ํšŒ์› ๋“ฑ๊ธ‰์— ๋”ฐ๋ผ ํ• ์ธ ์ •์ฑ…์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    - ํ• ์ธ ์ •์ฑ…์€ ๋ชจ๋“  VIP๋Š” 1000์›์„ ํ• ์ธํ•ด์ฃผ๋Š” ๊ณ ์ • ๊ธˆ์•ก ํ• ์ธ์„ ์ ์šฉํ•ด๋‹ฌ๋ผ. (๋‚˜์ค‘์— ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ
    ๋‹ค.)
    -ํ• ์ธ ์ •์ฑ…์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ํšŒ์‚ฌ์˜ ๊ธฐ๋ณธ ํ• ์ธ ์ •์ฑ…์„ ์•„์ง ์ •ํ•˜์ง€ ๋ชปํ–ˆ๊ณ , ์˜คํ”ˆ ์ง์ „๊นŒ์ง€ ๊ณ ๋ฏผ์„
    ๋ฏธ๋ฃจ๊ณ  ์‹ถ๋‹ค. ์ตœ์•…์˜ ๊ฒฝ์šฐ ํ• ์ธ์„ ์ ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ๋„ ์žˆ๋‹ค. (๋ฏธํ™•์ •)

๊ฐ์ฒด ์ง€ํ–ฅ์˜ ํ•ต์‹ฌ์ธ ๋‹คํ˜•์„ฑ์„ ์ด์šฉํ•ด ์—ญํ• (์ธํ„ฐํŽ˜์ด์Šค) ๊ณผ ๊ตฌํ˜„ (์‹ค์ œ ๊ตฌํ˜„ ๊ฐ์ฒด)์œผ๋กœ ๋‚˜๋ˆ ์„œ ๊ฐœ๋ฐœํ•˜์—ฌ ์ž์œ ๋กญ๊ฒŒ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ˜•์„ฑ์„ ์ด์šฉํ•ด ๊ฐœ๋ฐœํ•œ ๋•๋ถ„์— ํšŒ์› ์ €์žฅ์†Œ๋Š” ๋ฌผ๋ก ์ด๊ณ , ํ• ์ธ ์ •์ฑ…๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†์–ด๋ณด์ด์ง€๋งŒ! ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ…์„ ๊ฐœ๋ฐœํ•˜๊ณ  ์ ์šฉํ•  ๋•Œ ๋ช‡๊ฐ€์ง€์˜ ๋ฌธ์ œ๋“ค์ด ์ƒ๊น๋‹ˆ๋‹ค.

๊ทธ ๋ฌธ์ œ๋“ค์„ ์ค‘์ ์œผ๋กœ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

2. ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ… ๊ฐœ๋ฐœ ์‹œ ๋ฌธ์ œ์ 

๋‘๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์•ž์„  ์ฒซ๋ฒˆ์งธ ํฌ์ŠคํŠธ ์—์„œ ๋‚˜์™”๋˜ ๋‚ด์šฉ์ฒ˜๋Ÿผ

โ€ป ๋‹คํ˜•์„ฑ ๋งŒ์œผ๋กœ๋Š” OCP, DIP๋ฅผ ์ง€ํ‚ฌ ์ˆ˜๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

1.๊ธฐ์กด์˜ ๊ณ ์ • ํ• ์ธ ์ •์ฑ…

package com.mks.core.discount;

import com.mks.core.member.Grade;
import com.mks.core.member.Member;

public class FixDiscountPolicy implements DiscountPolicy{

    private int discountFixAmount = 1000; //1000์› ํ• ์ธ

    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP) {
            return discountFixAmount;
        }
        else{
            return 0;
        }
    }
}

2.์ƒˆ๋กœ์šด ์ •๋ฅ  ํ• ์ธ ์ •์ฑ…

package com.mks.core.discount;

import com.mks.core.member.Grade;
import com.mks.core.member.Member;

public class RateDiscountPolicy implements DiscountPolicy {

    private int discountPercent = 10;

    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){
            return price * discountPercent / 100;
        }
        else {
            return 0;
        }
    }
}

3.OrderServiceImpl ํด๋ž˜์Šค

public class OrderServiceImpl implements OrderService {
    
    private final MemberRepository memberRepository = new MemoryMemberRepository();
    
    //OrderServiceImpl์—์„œ ์ง์ ‘ ์ฃผ์ž…ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํ• ์ธ ์ •์ฑ…์ด ๋ฐ”๋€”๋•Œ ๋งˆ๋‹ค ๋ณ€๊ฒฝํ•ด์ค˜์•ผํ•จ 
    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
    // private final DiscountPolicy discountPolicy = new FixDiscountPolicy(); 


    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);


        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}

์šฐ์„  ์œ„์˜ 1๋ฒˆ์ฒ˜๋Ÿผ ๊ธฐ์กด์˜ ๊ณ ์ • ํ• ์ธ ์ •์ฑ…์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ…์„ ๋งŒ๋“ค๊ณ  ์ ์šฉํ•ด์•ผ ํ•˜๋”๋ผ๋„ ์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ์ž˜ ๊ตฌ๋ถ„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 2๋ฒˆ์ฒ˜๋Ÿผ ์ƒˆ๋กœ์šด ์ •๋ฅ  ํ• ์ธ ์ •์ฑ…์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ์ ์ด ์—†์–ด๋ณด์ด์ง€๋งŒ 3๋ฒˆ OrderServiceImpl ํด๋ž˜์Šค๋ฅผ ๋ณด๋ฉด ๋‘๊ฐ€์ง€ ๋ฌธ์ œ์ ์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘‰ DIP ์›์น™ ์œ„๋ฐ˜ - ์ถ”์ƒํ™”์™€ ๊ตฌ์ฒดํ™” ๋‘˜๋‹ค ์˜์กด

OrderServiceImpl ํด๋ž˜์Šค๋Š” MemberRepository ์ธํ„ฐํŽ˜์ด์Šค์™€ DiscountPolicy ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์˜์กดํ•˜๋ฉด์„œ ๊ตฌํ˜„ ํด๋ž˜์Šค์ธ MemoryMemberRepository์™€ RateDiscountPolicy ๊นŒ์ง€๋„ ์˜์กดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. OrderServiceImpl ํด๋ž˜์Šค๊ฐ€ ์ง์ ‘ ๊ฐ ์ธํ„ฐํŽ˜์ด์Šค์— ์ง์ ‘ ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•˜๋ฉฐ ์ธํ„ฐํŽ˜์ด์Šค, ๊ตฌํ˜„์ฒด ๋ชจ๋‘๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” DIP ์›์น™์— ์œ„๋ฐ˜ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๐Ÿ‘‰ OCP ์›์น™ ์œ„๋ฐ˜ - ํ• ์ธ ์ •์ฑ… ๋ณ€๊ฒฝ ์‹œ๋งˆ๋‹ค client ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •

OrderServiceImpl ํด๋ž˜์Šค์˜ ์ฃผ์„์— ์จ ์žˆ๋“ฏ์ด OrderServiceImpl ์—์„œ ์ง์ ‘ ์‹ค์ œ ํ• ์ธ ์ •์ฑ… ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํ• ์ธ ์ •์ฑ…์ด ๋ฐ”๋€”๋•Œ ๋งˆ๋‹ค ์ง์ ‘ ๋ณ€๊ฒฝํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด client ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— OCP ์›์น™์— ์œ„๋ฐ˜๋˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

3. ํ•ด๊ฒฐ์ฑ… - ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ!

ํ˜„์žฌ ์ƒํƒœ๋Š” ์ฃผ๋ฌธ ์„œ๋น„์Šค ๊ตฌํ˜„์ฒด๊ฐ€ ์ฃผ๋ฌธ ์„œ๋น„์Šค๋งŒ์„ ์ฑ…์ž„์ง€๊ณ  ์ œ๊ณตํ•˜๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์–ด๋–ค ํ• ์ธ ์ •์ฑ…์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š”์ง€๊นŒ์ง€ ์ง์ ‘ ๊ณ ๋ฅด๋ฉฐ ์ฑ…์ž„์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์–‘ํ•œ ์ฑ…์ž„์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋˜ SRP ์›์น™์„ ์œ„๋ฐ˜ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•  ํ•„์š”์„ฑ์ด ์ƒ๊น๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ์‚ฌ์šฉ ์—ญํ• ์—๋งŒ ์ถฉ์‹คํ•˜๋ฉด ๋˜์ง€ ๊ตฌ์„ฑ๊นŒ์ง€ ์ฑ…์ž„์งˆ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ „์ฒด ๋™์ž‘ ๋ฐฉ์‹์„ ๊ตฌ์„ฑํ•ด์ฃผ๊ธฐ ์œ„ํ•œ (๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์—ฐ๊ฒฐ(์ฃผ์ž…)) ๋ณ„๋„์˜ ์„ค์ • class๊ฐ€ ํ•„์š”ํ•ด์ง‘๋‹ˆ๋‹ค.!

๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ๊ฐ€ ์ด๋ค„์ง‘๋‹ˆ๋‹ค!

=> ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์—ฐ๊ฒฐ(์ฃผ์ž…)๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ด ๊ฐ๊ฐ์˜ ์ฑ…์ž„์„ ๊ฐ–๊ณ  ๋ถ„๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. (์‹คํ–‰ ์ฑ…์ž„ / ๊ตฌ์„ฑ ์ฑ…์ž„)

AppConfig.java

public class AppConfig {
    // ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด ๋™์ž‘ ๋ฐฉ์‹์„ ๊ตฌ์„ฑํ•ด์ฃผ๊ธฐ ์œ„ํ•œ ๋ณ„๋„์˜ ํด๋ž˜์Šค (๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์—ฐ๊ฒฐ/์ฃผ์ž…๋งŒ์„ ๋‹ด๋‹นํ•จ)
    public MemberService memberService(){
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

    public OrderService orderService(){
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
    }
}

AppConfig ํด๋ž˜์Šค ๋‚ด์˜ memberService ๋ฉ”์†Œ๋“œ๋Š” MemberService์˜ ๊ตฌํ˜„์ฒด์ธ MemberServiceImpl๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. MemberServiceImpl ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ MemberRepository์˜ ๊ตฌํ˜„์ฒด์ธ MemoryMemberRepository ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ค๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์ด
MemberServiceImpl ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„์ฒด์ธ MemoryMemberRepository ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

MemberServiceImpl.java

public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Override
    public void join(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

MemberServiceImpl๋Š” ์ด์ œ MemberRepository ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ DIP ์›์น™์„ ์ง€ํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

OrderServiceImpl.java

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member,itemPrice);

        return new Order(memberId,itemName,itemPrice,discountPrice);
    }
}

OrderServiceImpl๋Š” MemberRepository ์ธํ„ฐํŽ˜์ด์Šค์™€ DiscountPolicy ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•˜๋ฏ€๋กœ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ DIP ์›์น™์„ ์ง€ํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์œ„์™€ ๊ฐ™์ด MemberServiceImpl์™€ OrderServiceImpl๋Š” ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์ƒ์œผ๋กœ๋Š” ์–ด๋– ํ•œ ๊ตฌํ˜„ ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์˜ฌ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๊ณ , ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ๊ตฌํ˜„๊ฐ์ฒด๋ฅผ ์ฃผ์ž… ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

AppConfig class์˜ ๋“ฑ์žฅ์œผ๋กœ ์„ค์ • class (AppConfig) ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์—ฐ๊ฒฐ์„ ์‹œํ‚ค๊ณ  MemberServiceImpl์™€ OrderServiceImpl๋Š” ๊ฐ์ž ์ž์‹ ์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰๋งŒ ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์—ญํ• ์˜ ๋ถ„๋ฆฌ๊ฐ€ ์ด๋ค„์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์™ธ๋ถ€์—์„œ MemberServiceImpl์™€ OrderServiceImpl์— ์‹ค์ œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์„ DI (์˜์กด์„ฑ ์ฃผ์ž…)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

AppConfig.java

public class AppConfig {
    public MemberService memberService (){
        return new MemberServiceImpl(memberRepository());
    }

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

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

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

๋˜ํ•œ ์œ„์™€ ๊ฐ™์€ AppConfig ๋“ฑ์žฅ ์ด์ „์—๋Š” ๊ธฐ์กด ํ• ์ธ ์ •์ฑ…์—์„œ ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ…์„ ๋ฐ”๊ฟ€ ๋•Œ OrderServiceImpl ์—์„œ ์ง์ ‘ ์‹ค์ œ ํ• ์ธ ์ •์ฑ… ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— OrderServiceImpl์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋กœ์ธํ•ด OCP ์›์น™์ด ์œ„๋ฐ˜๋˜์—ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์€ AppCofig์˜ ๋“ฑ์žฅํ•˜๋ฉฐ ์‹ค์ œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— AppConfig ์—์„œ๋งŒ ์–ด๋–ค ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์ •ํ•˜๋ฉด ๋˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋กœ ์ธํ•ด OCP ์›์น™ ๋˜ํ•œ ์ง€์ผœ์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

AppConfig ๋“ฑ์žฅ ๊ฒฐ๊ณผ

AppConfig์˜ ๋“ฑ์žฅ์œผ๋กœ ๊ตฌํ˜„ ๊ฐ์ฒด๋“ค์€ ์ž์‹ ์˜ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ๋งŒ ๋‹ด๋‹นํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„ ๊ฐ์ฒด์˜ ์ฃผ์ž…์„ AppConfig ๊ฐ€ ๋‹ด๋‹นํ•˜๊ฒŒ ๋˜๋ฉฐ

ํ”„๋กœ๊ทธ๋žจ์˜ ์ œ์–ด ํ๋ฆ„์€ ์ด์ œ AppConfig ์—์„œ ๋‹ด๋‹นํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ช…ํ™•ํ•˜๊ฒŒ

์‹ค์ œ ๋กœ์ง์„ ๋‹ด๋‹นํ•˜๋Š” ์—ญํ• ๊ณผ

๊ฐ ๊ตฌํ˜„ ๊ฐ์ฒด๋“ค์„ ์ฃผ์ž…์‹œ์ผœ์ฃผ๋ฉฐ ํ”„๋กœ๊ทธ๋žจ์˜ ์ œ์–ด ํ๋ฆ„์„ ๋‹ด๋‹นํ•ด์ค„ ์—ญํ• ์ด ๋‚˜๋‰˜๋ฉฐ

๊ฐ์ฒด์ง€ํ–ฅ์˜ ์›์น™ ์ค‘ ์œ„๋ฐ˜๋˜์—ˆ๋˜ OCP ์›์น™ DIP ์›์น™๊นŒ์ง€ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋

์Šคํ”„๋ง์„ ๋” ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊น€์˜ํ•œ๋‹˜์˜ ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉฐ ์ •๋ฆฌํ•œ
๋‘๋ฒˆ์งธ ํฌ์ŠคํŠธ์˜€์Šต๋‹ˆ๋‹ค.
์Šคํ”„๋ง์˜ ์ •๋ง ํ•ต์‹ฌ์ด ๋˜๋Š” DI (์˜์กด์„ฑ ์ฃผ์ž…)๊ณผ IoC (์ œ์–ด์˜ ์—ญ์ „)์— ๋Œ€ํ•ด ๋‹ค์‹œ ํ•œ๋ฒˆ
์•Œ์•„๋ณด๊ณ  ๋” ๋ช…ํ™•ํžˆ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ™

์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ ์ฒซ๋ฒˆ์งธ ํฌ์ŠคํŠธ

1. ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์™€ ์Šคํ”„๋ง


Reference

๊น€์˜ํ•œ๋‹˜์˜ ์Šคํ”„๋ง ํ•ต์‹ฌ์›๋ฆฌ

Written on April 29, 2021