Java/Spring

[Spring] ์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ ๊ธฐ๋ณธํŽธ (1)

๋ฒผ๋ฆฌ01 2023. 12. 27. 00:08

https://start.spring.io/ ์—์„œ ์‹œ์ž‘ ํŒŒ์ผ ์ƒ์„ฑ(dependency X)

์ž๋ฐ” 21๋กœ ํ•˜๋ฉด ์˜ค๋ฅ˜๋‚˜๋‹ˆ๊นŒ 17๋กœ~!! 

 

setting - gradle - gradle prijects - build and run ์ธํ…”๋ฆฌ์ œ์ด๋กœ ๋ฐ”๊พธ๊ธฐ(gradleํ†ตํ•ด์„œ ์‹คํ–‰ํ•˜๋ฉด ๋А๋ฆผ)

 

๋‹จ์ถ•ํ‚ค ํ™•์ธ

setting - keymap

 

์‹ค๋ฌด์—์„œ๋Š” ๊ทธ๋ƒฅ ํ•ด์‹œ๋งต๋Œ€์‹  `concurrentHashMap`์„ ์‚ฌ์šฉํ•œ๋‹ค (๋™์‹œ์„ฑ ์ด์Šˆ)

 

์ธํ…”๋ฆฌ์ œ์ด ๋‹จ์ถ•ํ‚ค command shft enter (๋ฌธ์žฅ ์ž๋™์™„์„ฑ ๋‹จ์ถ•ํ‚ค)

command + option + V (์ฐธ์กฐ๋ณ€์ˆ˜ ์ž๋™์ƒ์„ฑ)

option + Enter (์ž„ํฌํŠธ ๋“ฑ ์˜ค๋ฅ˜๋‚œ ๊ณณ์œผ๋กœ ์ด๋™)

command + shifh + T (ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ)

command + E + Enter (์ด์ „ ์ฐฝ์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ)

command + E ํžˆ์Šคํ† ๋ฆฌ ์ฐฝ

 

๊ตฌํ˜„์ฒด๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ ์ฃผ๋กœ ํด๋ž˜์Šค ์ด๋ฆ„์— Impl์„ ๋ถ™์ž„

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์„ฑ๊ณตํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ ์‹คํŒจํ•˜๋Š” ์ผ€์ด์Šค๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค(์˜ˆ์™ธ ํ„ฐ์ง€๋Š” ๊ฒƒ ํ™•์ธํ•˜๊ธฐ)

`Assertions`

ํŒจํ‚ค์ง€: org.assertj.core.api.Assertions

 


 

 

//    ํ• ์ธ์ •์ฑ…
//    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();

//    ์œ„ ์ฝ”๋“œ๋Š” ํด๋ผ์ด์–ธํŠธ(ํ•ด๋‹น ํด๋ž˜์Šค)๊ฐ€ ๊ตฌํ˜„์ฒด์— ์ง์ ‘ ์˜์กดํ•˜๊ณ  ์žˆ์Œ(DIP ์œ„๋ฐ˜, OCP ์œ„๋ฐ˜)
//    ํ• ์ธ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋จ

 

 

์œ„ ์ฝ”๋“œ๋Š” ๊ฒ‰๋ณด๊ธฐ์—๋งŒ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๋ชจ์–‘์„ ํ•  ๋ฟ ์‹ค์ œ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์„ ์–ธํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ `FixDiscountPolicy`๋‚˜ `RateDiscountPolicy`๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค.(๊ตฌ์ฒด ํด๋ž˜์Šค๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ์Œ)

ํ• ์ธ ์ •์ฑ…์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ํด๋ผ์ด์–ธํŠธ`OrderServiceImpl`์˜ ์ฝ”๋“œ๋ฅผ ๊ณ ์ณ์•ผํ•œ๋‹ค. OCP/DIP๋ฅผ ์œ„๋ฐ˜ํ•˜๊ณ  ์žˆ๋‹ค.

๊ฐ€์†”๋ฆฐ ์ž๋™์ฐจ์—์„œ ์ „๊ธฐ ์ž๋™์ฐจ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ๋ผ์ด์„ผ์Šค๋ฅผ ์ƒˆ๋กœ ๋”ฐ์•ผํ•˜๋Š” ๊ฒฉ์ด๋‹ค.

 

์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๐Ÿ—ฃ๏ธ  ์˜์กด ๊ด€๊ณ„๋ฅผ ๋А์Šจํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ์ž์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ `discountPolicy`๋ฅผ ๋ฐ›๋Š” ๋“ฑ์˜ ๋ฐฉ์‹์œผ๋กœ ๋ฐ–์œผ๋กœ๋ถ€ํ„ฐ `DiscountPolicy`๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์™€์„œ ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ์‹์„ ์ด์šฉํ•˜๋ฉด ์–ด๋–จ๊นŒ์šฉ 

 

 

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ตฌํ˜„์ฒด๊ฐ€ ์•„๋‹Œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ์˜์กดํ•ด์•ผํ•œ๋‹ค.

 

private DiscountPolicy discountPolicy;

 

 

๊ทธ๋Ÿฐ๋ฐ ์ด ์ƒํƒœ๋กœ ์‹คํ–‰ํ•˜๋ฉด `NullpointException`์ด ๋ฐœ์ƒํ•œ๋‹ค. (๋‹น์—ฐํ•จ.. null์ž„)

ํด๋ผ์ด์–ธํŠธ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์œผ๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค. (๋‹น์—ฐํ•จ...... ์ธํ„ฐํŽ˜์ด์Šค์ž„)

๊ทธ๋Ÿฌ๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ๊นŒ? -> ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํด๋ผ์ด์–ธํŠธ์ธ `OrderServiceImpl`์— `DiscountPolicy`์˜ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•ด์ค˜์•ผํ•œ๋‹ค!

 

๊ฐ์ฒด ์ฃผ์ž…๋งŒ์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ๋‹ค. -> `AppConfig`

๋ฐ–์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

๊ณต์—ฐ์—์„œ ๋ฐฐ์šฐ๋Š” ์—ฐ๊ธฐ๋งŒ์„ ๋‹ด๋‹นํ•˜๊ณ , ๋ฐฐ์šฐ ์„ญ์™ธ๋Š” ๊ธฐํš์ž๊ฐ€ ํ•œ๋‹ค.

 

//	public class OrderServiceImpl implements OrderService

	private final MemberRepository memberRepository;

//    ํ• ์ธ์ •์ฑ…
//    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
//    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
//    ์œ„ ์ฝ”๋“œ๋Š” ํด๋ผ์ด์–ธํŠธ(ํ•ด๋‹น ํด๋ž˜์Šค)๊ฐ€ ๊ตฌํ˜„์ฒด์— ์ง์ ‘ ์˜์กดํ•˜๊ณ  ์žˆ์Œ(DIP ์œ„๋ฐ˜, OCP ์œ„๋ฐ˜)
    private DiscountPolicy discountPolicy;

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

 

public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

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

 

public class AppConfig {

    public MemberService memberService(){
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

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

 

 

`AppConfig`๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‹ค์ œ ๋™์ž‘์— ํ•„์š”ํ•œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

`AppConfig`์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ  ํด๋ผ์ด์–ธํŠธ`OrderServiceImpl`์—๊ฒŒ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…(Injection)ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ํด๋ž˜์Šค๋Š” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ „ํ˜€ ๋ชจ๋ฅด๊ณ  ์žˆ๋‹ค. 

ํด๋ผ์ด์–ธํŠธ์˜ ์ž…์žฅ์—์„œ ๋ณด๋ฉด ๋งˆ์น˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ•ด์„œ DI(Dependency Injection: ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(์˜์กด์„ฑ ์ฃผ์ž…))์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

public class MemberApp {
    public static void main(String[] args) {

        AppConfig appConfig = new AppConfig();
//        MemberService memberService = new MemberServiceImpl();
        MemberService memberService = appConfig.memberService();
        
        .
        .
        .

 

public class OrderApp {
    public static void main(String[] args) {
        AppConfig appConfig = new AppConfig();
        MemberService memberService = appConfig.memberService();
        OrderService orderService = appConfig.orderService();
        .
        .
        .

 

 

Main์—์„œ๋„ `AppConfig`๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ด์ค€๋‹ค. ๋‘˜ ๋‹ค ๊ตฌ์ฒด ํด๋ž˜์Šค์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์˜์กดํ•œ๋‹ค. (๊ตฌ์ฒด ํด๋ž˜์Šค๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๊ณ  ์žˆ๋‹ค -> ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค)

 

`@BeforeEach`

ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์—์„œ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋งˆ๋‹ค ์ ์šฉํ•ด์•ผํ•  ๋•Œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ(์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๋ฉ”์„œ๋“œ) ์œ„์— ๋ถ™์ด๋Š” ์• ๋„ˆํ…Œ์ด์…˜

 

public class MemberServiceTest {

    MemberService memberService;

    @BeforeEach
    public void beforeEach(){
        AppConfig appConfig = new AppConfig();
        memberService = appConfig.memberService();
    }

    @Test
    void join() {
    .
    .
    .

 

`@BeforeEach`๋•๋ถ„์— ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง

 

 

์ด์ œ ํด๋ผ์ด์–ธํŠธ `OrderServiceImpl`์€ ๊ตฌ์ฒด ํด๋ž˜์Šค๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ •๋ณด๋ฅผ ์•Œ ํ•„์š” ์—†์ด ์ž์‹ ์˜ ์—ญํ• ์— ์ถฉ์‹คํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ `AppConfig`๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ•œ ๋ˆˆ์— ์ธ์ง€ํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ ๋ด๋„ ์–ด๋–ค ์ผ์„ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ๋ฆฌํŒฉํ„ฐ๋ง ํ•ด์ฃผ๊ธฐ๋กœ ํ•œ๋‹ค.

 

1. ์—ญํ• ๊ณผ ๊ตฌํ˜„ ๋ถ„๋ฆฌ

2. ์—ญํ• ์ด ์ž˜ ๋“œ๋Ÿฌ๋‚˜๋„๋ก ์ž‘์„ฑ

3. ์ค‘๋ณต์„ ์ œ๊ฑฐํ•จ (new  ์–ด์ฉŒ๊ตฌ ๊ตฌ๊ตฌ์ ˆ์ ˆ ์ฝ”๋“œ๋ฅผ ๋ฉ”์„œ๋“œ๋กœ ๋นผ๋‚ธ๋‹ค)

 

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

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

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

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

}

 

๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ ๋ด๋„ ์–ด๋–ค ์ผ์„ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. (๊ตฌ์ฒด ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฆฌํ„ดํ•˜๋Š” ์—ญํ• )

๋ฉค๋ฒ„ ์„œ๋น„์Šค, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ, ์˜ค๋”์„œ๋น„์Šค, ํ• ์ธ์ •์ฑ…์ด ๋ฐ”๋€Œ์–ด๋„ ํ•ด๋‹น ํด๋ž˜์Šค๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ๋ณด์ž. ๊ธฐํš์ž๊ฐ€ ๊ธฐ์กด์˜ ์ •์•ก ํ• ์ธ ์ •์ฑ… `FixDiscountPolicy`์—์„œ ์ •๋ฅ  ํ• ์ธ ์ •์ฑ… `RateDiscountPolicy`๋กœ ๋ณ€๊ฒฝํ•˜์ž๊ณ  ์š”๊ตฌํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์–ด๋А ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๊ฒ ๋Š”๊ฐ€?

 

๐Ÿ—ฃ๏ธ `AppConfig`์˜ ๋งจ ๋งˆ์ง€๋ง‰์ค„์ธ `discountPolicy()` ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹น

ใ„ด ใ…‡ใ…‡ ๋งž์Œ 

 

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

 

ํ• ์ธ ์ •์ฑ…์ด ๋‹จ ํ•œ ์ค„์˜ ์ฝ”๋“œ ์ˆ˜์ •์œผ๋กœ ์†์‰ฝ๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค.

 

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

OCP(ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๊ณ  ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€์žˆ๋‹ค)์™€ DIP(์ถ”์ƒํ™”์— ์˜์กด)๊ฐ€ ์•„์ฃผ ์ž˜ ์ง€์ผœ์ง€๊ณ  ์žˆ๋‹ค.

 

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

2. OCP "์†Œํ”„ํŠธ์›จ์–ด ์š”์†Œ๋Š” ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ์œผ๋‚˜ ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€์žˆ์–ด์•ผ ํ•œ๋‹ค." - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉ ์˜์—ญ๊ณผ ๊ตฌ์„ฑ ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆ„์–ด ์ •์ฑ…์ด ๋ณ€๊ฒฝ๋˜์–ด ์ˆ˜์ •์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์˜์—ญ๋งŒ ์ˆ˜์ •ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•จ.

3. DIP "๊ตฌ์ฒด ํด๋ž˜์Šค๋ฅผ ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค." - ์˜์กด์„ฑ ์ฃผ์ž…(DI)๋Š” ์ด ์›์น™์„ ๋”ฐ๋ฅด๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ž„.

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ•˜๋‚˜์˜ ๊ณต์—ฐ์œผ๋กœ ์ƒ๊ฐํ•ด๋ณด์ž.

๋ฐฐ์šฐ๋Š” ์—ฐ๊ธฐ๋งŒ ํ•˜๊ณ , ๊ธฐํš์ž๋Š” ๊ธฐํš์„ ํ•˜๊ณ , ๊ฐ๋…์€ ๊ฐ๋…๋งŒ ํ•œ๋‹ค. ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

`AppConfig`๋Š” ์ „์ฒด ๋™์ž‘ ๋ฐฉ์‹์„ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—ฐ๊ฒฐํ•˜๋Š” ์ฑ…์ž„๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ์—ญํ• ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ถŒํ•œ์ด ์ค„์–ด๋“ค์–ด ์ฑ…์ž„์ด ๋ช…ํ™•ํ•ด์กŒ๋‹ค.

 


 

 

์ œ์–ด์˜ ์—ญ์ „: IoC(Inversion of Control) 

์ด์ „์—๋Š” ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„ ๊ฐ์ฒด `OrderServiceImpl`์ด ์Šค์Šค๋กœ ํ•„์š”ํ•œ ์„œ๋ฒ„ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—ฐ๊ฒฐํ•˜๊ณ  ์‹คํ–‰ํ–ˆ๋‹ค.(ํ”„๋กœ๊ทธ๋žจ์˜ ์ œ์–ด ํ๋ฆ„์„ ์Šค์Šค๋กœ ์กฐ์ข…ํ•จ)

`AppConfig`๊ฐ€ ๋“ฑ์žฅํ•œ ์ดํ›„๋กœ ๊ตฌํ˜„ ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ๋งŒ ๋‹ด๋‹นํ•œ๋‹ค. ์ฆ‰, ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„ ๊ฐ์ฒด๋Š” ์Šค์Šค๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋–ป๊ฒŒ ํ˜๋Ÿฌ๊ฐ€๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๊ณ  ์žˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ์ œ์–ด ํ๋ฆ„์„ `AppConfig`๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. 

์ด๋ ‡๋“ฏ ์ œ์–ด์˜ ํ๋ฆ„์„ ์Šค์Šค๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์ œ์–ด์˜ ์—ญ์ „(IoC)๋ผ๊ณ  ํ•œ๋‹ค.

 

๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋Œ€์‹  ์ œ์–ดํ•˜๊ณ  ๋Œ€์‹  ์‹คํ–‰ํ•˜๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ(์ œ์–ด์˜ ์—ญ์ „)

๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋‚ด๊ฐ€ ์ œ์–ดํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

์ •์ ์ธ ํด๋ž˜์Šค ์˜์กด ๊ด€๊ณ„: ํด๋ž˜์Šค๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” import ํด๋ž˜์Šค๋งŒ ๋ด๋„ ์˜์กด ๊ด€๊ณ„๋ฅผ ์‰ฝ๊ฒŒ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค. (์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ ๋„ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋‹ค.) `OrderServiceImpl` ๊ตฌ์ฒด ํด๋ž˜์Šค๋Š” `DiscountPolicy` ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•œ๋‹ค. 

 

์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…(์˜์กด์„ฑ ์ฃผ์ž…): DI(Dependency Injection)

`OrderServiceImpl` ๊ตฌ์ฒด ํด๋ž˜์Šค๋Š” `DiscountPolicy` ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ์ฃผ์ž…๋˜๋Š” ๊ฒƒ์ด ์–ด๋–ค ๊ฐ์ฒด์ธ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๋‹ค.(ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ „ํ˜€ ๋ชจ๋ฅธ๋‹ค.) ์ด๋ฅผ ๋™์ ์ธ ํด๋ž˜์Šค ์˜์กด ๊ด€๊ณ„๋ผ๊ณ  ํ•œ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์— ์™ธ๋ถ€์—์„œ ์‹ค์ œ ๊ตฌํ˜„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ด์ฃผ์–ด ์˜์กด๊ด€๊ณ„๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

`AppConfig`์ฒ˜๋Ÿผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋ฉด์„œ ์˜์กด ๊ด€๊ณ„๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์„ IoC ์ปจํ…Œ์ด๋„ˆ ๋˜๋Š” DI ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•œ๋‹ค.