JiwonDev

#4 ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ(SOC), ์˜์กด์„ฑ ์ฃผ์ž…(DI)

by JiwonDev

์ด ๊ธ€์€ 2021.08.01 - [Backend/Spring Core] - #3 ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ์˜ˆ์ œ ๋งŒ๋“ค๊ธฐ์™€ ์ด์–ด์ง€๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

#3 ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ์˜ˆ์ œ ๋งŒ๋“ค๊ธฐ

ํ•ด๋‹น ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ์ธํ”„๋Ÿฐ ๊ฐ•์˜๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ๊น€์˜ํ•œ ์˜ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜ ๊ด€์‹ฌ ์žˆ๋Š” ๊ฐ•์˜๊ฐ€ ์žˆ๋‹ค๋ฉด ์ง€๊ธˆ ๋‹น์žฅ ์‹œ์ž‘ํ•˜์„ธ์š”! ์ธํ”„๋Ÿฐ์€ ์–ธ์ œ๋‚˜ ๋‹น์‹ ์˜ ์„ฑ์žฅ์„ ์‘์›

jiwondev.tistory.com

 

# ํ•œ ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์ฑ…์ž„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

ํ˜„์‹ค์—์„œ ์ผ์–ด๋‚˜๋Š” ๋Œ€๊ทœ๋ชจ ๊ณต์—ฐ์„ ์ƒ๊ฐํ•ด๋ณด์ž. ๊ฐ๊ฐ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐฐ์—ญ(์—ญํ• )์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ๋•Œ, ๊ทธ ๋ฐฐ์—ญ์„ ์—ฐ๊ธฐํ•˜๋Š” ๊ตฌํ˜„์ฒด(์—ฐ๊ธฐ์ž)๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ๋ˆ„๊ฐ€ ๋‹ด๋‹นํ• ๊นŒ? ์ด๋Š” ๊ฐ๋…์ด ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด์ง€ ๋ฐฐ์šฐ๋“ค์ด ์ง์ ‘ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

 

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

 

# ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์ž, SOC(Separation Of Concerns) 

๊ณต์—ฐ์—์„œ ๋‹ด๋‹น ๋ฐฐ์šฐ(๊ตฌํ˜„์ฒด)๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ๊ณต์—ฐ์˜ ์ฃผ์ธ๊ณต์˜ ํ–‰๋™(์—ญํ• )์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋ฐฐ์šฐ๋Š” ๋ณธ์ธ์˜ ์—ญํ• ์ธ ๋ฐฐ์—ญ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์—๋งŒ ์ง‘์ค‘ํ•ด์•ผ ํ•œ๋‹ค.
  • ์—ฐ๊ธฐ์ž๋Š” ๋‹ค๋ฅธ ๋ฐฐ์—ญ์„ ๋งก๊ฒŒ ๋˜๋”๋ผ๋„ ๊ณต์—ฐ์„ ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.
  • ๊ณต์—ฐ์„ ๊ตฌ์„ฑํ•˜๊ณ , ๋‹ด๋‹น ๋ฐฐ์šฐ๋ฅผ ์„ญ์™ธํ•˜๋Š” ๊ฒƒ์€ ๋ณ„๋„์˜ ๊ณต์—ฐ ๊ธฐํš์ž๊ฐ€ ๋‹ด๋‹นํ•ด์•ผํ•œ๋‹ค.
  • ๋ฐฐ์šฐ์™€ ๊ณต์—ฐ ๊ธฐํš์ž์˜ ์ฑ…์ž„์„ ํ™•์‹คํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜์ž.

์ฆ‰, ๊ณต์—ฐ๊ธฐํš์ž๋ฅผ ๋‹ด๋‹นํ•˜๋Š” AppConfig ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

public class AppConfig {
	// MemberService๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๊ธฐํš์ž
    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

	// OrderService๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๊ธฐํš์ž
    public OrderService orderService() {
        return new OrderServiceImpl(
                new MemoryMemberRepository(),
                new FixDiscountPolicy());
    }
}

AppConfig์—์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์•„๋ž˜์™€ ๊ฐ™์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

public class MemberServiceImpl implements MemberService {
    // [... = new ๊ตฌํ˜„์ฒด ]์ฒ˜๋Ÿผ ์ง์ ‘ ํ• ๋‹นํ•ด์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์˜์กดํ•˜๋Š” ๋ถ€๋ถ„์„ ์—†์• ์ฃผ์—ˆ๋‹ค
    public final MemberRepository memberRepository;

    // ๊ทธ ๋Œ€์‹  AppConfig์—์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.
    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);
    }
}

์ด๋ ‡๊ฒŒ ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„์ฒด, ์ฆ‰ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ์‹์œผ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค. ๊ตฌํ˜„์ฒด๊ฐ€ ๋ฐ”๋€๋‹ค ํ•˜๋”๋ผ๋„ ํด๋ผ์ด์–ธํŠธ๋Š” ์ธํ„ฐํŽ˜์ด์Šค(์—ญํ• )์—๋งŒ ์˜์กดํ•˜๊ธฐ์— ์ „ํ˜€ ์ƒ๊ด€์—†๋‹ค.  

  • AppConfig๋Š” ์•ฑ์˜ ์‹ค์ œ ๋™์ž‘์— ํ•„์š”ํ•œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    - ( MemberServiceImpl, MemoryMemberRepository, OrderServiceImpl, FixDiscountPolicy )

  • AppConfig๋Š” ์ƒ์„ฑํ•œ ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด์„œ ์ฃผ์ž…, ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.
    - MemberServiceImpl -> MemoryMemberRepositroy
    - OrderServiceImpl -> MemoryMemberRepository, FixDiscountPolicy
  • ์ฆ‰, ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•œ๋‹ค. ์ฆ‰ ์˜์กด๊ด€๊ณ„์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์€ ์™ธ๋ถ€์— ๋งก๊ธฐ๊ณ  ์‹คํ–‰์—๋งŒ ์ง‘์ค‘ํ•˜๋ฉด ๋œ๋‹ค. ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


# DI ์˜ ๋“ฑ์žฅ (Dependency Injection)

AppConfig ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ memoryMemberRepository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฐธ์กฐ๊ฐ’์„ memberServiceImpl์˜ ์ƒ์„ฑ์ž๋กœ ์ฃผ์ž…ํ•œ๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ์—์„œ ๊ตฌํ˜„์ฒด(memoryMemberRepository)์˜ ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋‹ค๊ณ  ํ•ด์„œ, ๋ฐ”๋€Œ์–ด์•ผ ํ•  ๋ถ€๋ถ„์ด ์žˆ์„๊นŒ?

public interface MemberService {
    void join(Member member);
    Member findMember(Long memberId);
}

public class MemberServiceImpl implements MemberService {
    // [... = new ๊ตฌํ˜„์ฒด ]์ฒ˜๋Ÿผ ์ง์ ‘ ํ• ๋‹นํ•ด์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์˜์กดํ•˜๋Š” ๋ถ€๋ถ„์„ ์—†์• ์ฃผ์—ˆ๋‹ค
    public final MemberRepository memberRepository;

    // ๊ทธ ๋Œ€์‹  AppConfig์—์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.
    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)์˜ ์ž…์žฅ์—์„œ ๋ณด๋ฉด, ๋งˆ์น˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ์„ค๊ณ„๋ฅผ DI(Dependency Injection), ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ฒŒ ๋˜์—ˆ๋‹ค.

 


# ๊ธฐํš์ž, AppConfig๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•ด๋ณด์ž

ํ˜„์žฌ AppConfig๋Š” ๋‹จ์ˆœํ•˜๊ฒŒ ์ž‘์„ฑํ•œ๊ฑฐ๋ผ, ๊ฐ์ฒด์ง€ํ–ฅ์—์„œ ๋งํ•˜๋Š” ์ข‹์€ ์ฝ”๋“œ๋ผ๊ณ  ๋ณด๊ธฐ์—๋Š” ์–ด๋ ต๋‹ค. ์ฝ”๋“œ์˜ ์ค‘๋ณต์ด ์žˆ๊ณ  ์—ญํ• ์— ๋”ฐ๋ฅธ ๊ตฌํ˜„์„ ์•Œ๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ฅผ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•ด๋ณด์ž.

// ๊ธฐ์กด์˜ ์ฝ”๋“œ
public class AppConfig {
    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

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

์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์„ค๊ณ„๋„์— ๋งž์ถฐ AppConfig ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

/*
    ๊ตฌํ˜„์ฒด ์ƒ์„ฑ(memberRepository)์˜ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  
    AppConfig ๋งŒ์œผ๋กœ ์—ญํ™œ๊ฐ€ ๊ตฌํ˜„ํด๋ž˜์Šค๋ฅผ ์•Œ์ˆ˜์žˆ๊ฒŒ ๋ฐ”๋€Œ์—ˆ๋‹ค.
 */
public class AppConfig {
    // MemberService
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

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

    // Repository
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

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

๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ new๋กœ ์ƒ์„ฑํ•˜๋Š”๊ฒŒ ์•„๋‹Œ, AppConfig๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์ž.

@DisplayName("OrderService ํด๋ž˜์Šค์˜")
class OrderServiceTest {
    private OrderService orderService;
    private MemberService memberService;

    @BeforeEach
    void beforeEach() {
        AppConfig appConfig = new AppConfig();
        memberService = appConfig.memberService();
        orderService = appConfig.orderService();
    }
    ... ์ƒ๋žต ...

์ด๋ ‡๊ฒŒ ๊นŒ์ง€ ํ•ด์ฃผ๋ฉด, ์šฐ๋ฆฌ๋Š” ๋“œ๋””์–ด DIP์™€ OCP๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์„ค๊ณ„๋ฅผ ํ–ˆ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ์ธํ„ฐํŽ˜์ด์Šค(์—ญํ• )๋งŒ์„ ๋ณด๊ณ  ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฐ”๋€Œ์—ˆ๋‹ค.
  • ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ์œผ๋‚˜ ์ˆ˜์ •์—๋Š” ๋‹ซํ˜€์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค. 

# ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์™€ ์•…๋• ๊ธฐํš์ž์˜ ํ• ์ธ์ •์ฑ… ์ ์šฉ

๋‹ค์‹œ ์ฒ˜์Œ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ, ์ด์ „ ๊ธ€์—์„œ ๋งํ–ˆ๋˜ ์ƒˆ๋กœ์šด ํ• ์ธ์ •์ฑ…์„ ์ ์šฉ์‹œ์ผœ๋ณด์ž. ์–ด๋–ค ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜๋ฉด ๋ ๊นŒ?

public class AppConfig {
	... ์ƒ๋žต ...

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

์ฆ‰, AppConfig๋ผ๋Š” ๊ฐ๋… ์—ญํ• ์˜ ๊ฐ์ฒด๊ฐ€ ์ƒ๊น€์œผ๋กœ์„œ ์•ฑ ์ž์ฒด๊ฐ€ ์„œ๋น„์Šค ์‚ฌ์šฉ์˜์—ญ๊ณผ ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑ(Configuration)ํ•˜๋Š” ์˜์—ญ์œผ๋กœ ๋ถ„๋ฆฌ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

FixDiscount -> RateDiscount๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค ํ•œ๋“ค, ์‚ฌ์šฉ์˜์—ญ ์ฝ”๋“œ๋Š” ์ „ํ˜€ ์˜ํ–ฅ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

 


# ์„ค๊ณ„์˜ ๋ฐœ์ „, ๊ฐ์ฒด์ง€ํ–ฅ ์ ์šฉ

์šฐ๋ฆฌ๊ฐ€ ์ด์ „ ๊ธ€๊ณผ ์—ฌ๊ธฐ๊นŒ์ง€ ํ–ˆ๋˜ ๊ณ ๋ฏผ๋“ค์€, ์‹ค์ œ ์ž๋ฐ” ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ณ ๋ฏผํ–ˆ๋˜ ๋‚ด์šฉ๊ณผ ๋™์ผํ•˜๋‹ค.

1. ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋…, ๋‹คํ˜•์„ฑ์„ ๊ตฌํ˜„

2. ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ… ๊ฐœ๋ฐœ => ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด์„œ ๋‹คํ˜•์„ฑ์„ '๊ตฌํ˜„ ํ•œ ๊ฒƒ'์ฒ˜๋Ÿผ ๋ณด์ž„.

3. ์ƒˆ๋กœ์šด ํ• ์ธ ์ •์ฑ…์˜ ๋ฌธ์ œ์  => ๊ตฌํ˜„์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด, ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋„ ๋ณ€๊ฒฝํ•ด์•ผํ•จ. DIP ์œ„๋ฐ˜

4. ํ•ด๊ฒฐ์ฑ…. ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ => ๊ฐ๋… ์—ญํ• ์˜ AppConfig์˜ ๋“ฑ์žฅ.

5. AppConfig๋„ ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ๋ฆฌํŽ™ํ† ๋ง

 

๋ชจ๋ฅผ ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ๋ฌธ์ œ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์šฐ๋ฆฌ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ SRP, DIP, OCP๋ฅผ ์ ์šฉ์‹œ์ผฐ๋‹ค.

 

@1. SRP ๋‹จ์ผ ์ฑ…์ž„ ์›์น™

ํ•œ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

[ํšŒ์›-์ฃผ๋ฌธ]์€ ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด์—์„œ ์ง์ ‘ ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑ, ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ๋„ํ•œ ์ฑ…์ž„์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค. ์ด๋ฅผ SRP ์›์น™์— ๋”ฐ๋ผ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์˜€๊ณ , ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—ฐ๊ฒฐํ•˜๋Š” ์ฑ…์ž„์„ AppConfig๋กœ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค. ์ด์ œ ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด๋Š” [ํšŒ์›-์ฃผ๋ฌธ]์„œ๋น„์Šค๋ผ๋Š” ํ•˜๋‚˜์˜ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฑ…์ž„๋งŒ ๋งก๊ฒŒ ๋˜์—ˆ๋‹ค.

 

@2. DIP ์˜์กด๊ด€๊ณ„ ์—ญ์ „ ์›์น™

์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ์ง€, ๊ตฌ์ฒดํ™”์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

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

 

@3. OCP ๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™

์†Œํ”„ํŠธ์›จ์–ด ์š”์†Œ๋Š” ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ์œผ๋‚˜, ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ฒ˜์Œ์—๋Š” ๋ง๋„์•ˆ๋˜๋Š” ๋ง์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์•„๋ฌด๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋“ค, ๋ณ€๊ฒฝ์„ ์•ˆํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ํ™•์žฅ์„ ํ• ๊นŒ? ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋‹ต์„ ์•Œ๊ณ ์žˆ๋‹ค. ๋‹คํ˜•์„ฑ์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ํด๋ผ์ด์–ธํŠธ๊ฐ€ DIP๋ฅผ ์ง€ํ‚ค๋„๋ก๋งŒ๋“ค์—ˆ๊ณ , ์•ฑ์˜ ์‚ฌ์šฉ์˜์—ญ๊ณผ ๊ตฌ์„ฑ(config)์˜์—ญ์„ ๋ถ„๋ฆฌ์‹œ์ผœ ๊ฐœ๋ฐœ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

์ด์ œ ํ• ์ธ์ •์ฑ…๋ณ€๊ฒฝ์ด๋‚˜ ํšŒ์› ์ €์žฅ์†Œ๊ฐ€ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๊ตฌํ˜„์ฒด๋กœ ๋ฐ”๋€Œ๋”๋ผ๋„, AppConfig ๊ตฌ์„ฑ์˜์—ญ์—์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…๋งŒ ๋ฐ”๊ฟ”์ฃผ๊ฒŒ๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ์˜ ์ฝ”๋“œ์˜ ์ˆ˜์ •์—†์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ์†Œํ”„ํŠธ์›จ์–ด ์š”์†Œ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ํ™•์žฅ, ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ ์„œ๋น„์Šค ์‚ฌ์šฉ์˜์—ญ์˜ ๋ณ€๊ฒฝ์€ ๋‹ซํ˜€์žˆ๊ฒŒ ๋œ๋‹ค.

 

 

์ด์ œ ๋‹ค์Œ ๊ธ€์—๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์™€ ๋”๋ถˆ์–ด, ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ์ธ IoC, DI ๊ทธ๋ฆฌ๊ณ  ์ปจํ…Œ์ด๋„ˆ์— ๋Œ€ํ•ด ๋ฐฐ์›Œ๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ