๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

Spring AOP - (1) ํ”„๋ก์‹œ ํŒจํ„ด, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

by ์ฃผ๋ฐœ2 2021. 8. 27.
๋ฐ˜์‘ํ˜•

๐Ÿ“Ž  ๊ธ€๋˜ 6๊ธฐ ํฌ์ŠคํŒ…

1. ๋ฏธ์น˜๋„๋ก ๋”์› ๋˜ 7์›”์˜ ํšŒ๊ณ 

 

2. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒŒ์‹œ๋ฌผ์„ ์ž‘์„ฑํ•  ๋•Œ์˜ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ

 

3. Spring AOP - (1) ํ”„๋ก์‹œ ํŒจํ„ด, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

 

4. [MySQL] - ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€(Isolation level)

 

5. Spring AOP - (2) AOP ๊ฐœ๋… ๋ฐ ์‹ค์Šต

 

6. ์ธํ…”๋ฆฌ์ œ์ด(IntelliJ) - ๋””๋ฒ„๊น…(Debugging) ํ•˜๊ธฐ

 

7. [Java, ๋””์ž์ธํŒจํ„ด] - ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด(Singleton Pattern)

 

8. ์›”๊ฐ„ ์ฝ”๋“œ๋ฆฌ๋ทฐ Ver_0.1: ์ปค๋ฆฌ์–ด ์„ฑ์žฅ CODE ์„ธ๋ฏธ๋‚˜ ์ •๋ฆฌ

 

9. ํฌ์ŠคํŠธ๋งจ(API ํ…Œ์ŠคํŠธ) ํ™œ์šฉํ•˜๊ธฐ

 

10. ๋œป๊นŠ์€ 2021๋…„ ํšŒ๊ณ 

 


๐Ÿ“Ž  Spring AOP(Aspect Oriented Programming)

ํฌ์ŠคํŒ…์— ์ž‘์„ฑํ•œ ์˜ˆ์ œ ์ฝ”๋“œ๋Š” ๊นƒํ—ˆ๋ธŒ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค :)

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์ด๋ฒˆ ์‹œ๊ฐ„์— ์ •๋ฆฌํ•  ๋‚ด์šฉ์€ ์Šคํ”„๋ง AOP(Aspect Oriented Programming) ์ž…๋‹ˆ๋‹ค.

 

์ตœ๊ทผ ๋ช‡๋ช‡ ๋ฉด์ ‘์—์„œ AOP์— ๋Œ€ํ•ด ์งˆ๋ฌธ์„ ๋ฐ›์€์ ์ด ์žˆ์—ˆ๊ณ , ์‹ค์ œ ์ ์šฉ์„ ํ•ด๋ณด๊ฑฐ๋‚˜ ์ •ํ™•ํ•˜๊ฒŒ ์ดํ•ด๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๋Š” ์•„๋‹ˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒˆ ๊ธฐํšŒ์— ํ™•์‹คํ•˜๊ฒŒ ์ดํ•ด๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ํฌ์ŠคํŒ…์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜‚

 

๋จผ์ € ํฌ์ŠคํŒ…์˜ ๋ชฉ์ ์ธ ์Šคํ”„๋ง AOP์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ธฐ ์ „์— ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ”„๋ก์‹œ์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด

์ •๋ฆฌ๋ฅผ ํ•œ ํ›„ ์Šคํ”„๋ง AOP์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ํฌ์ŠคํŒ…์˜ ๋ชฉ์ฐจ ์ž…๋‹ˆ๋‹ค.

  • ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• 1 - ํ”„๋ก์‹œ ํŒจํ„ด
  • ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• 2 - ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด
  • Spring AOP ๊ฐœ๋…
  • Spring AOP ํŠน์ง•
  • Spring AOP ์šฉ์–ด
  • Spring AOP ์‹ค์Šต 1
  • Spring AOP ์–ด๋…ธํ…Œ์ด์…˜
  • Spring AOP ์‹ค์Šต 2
  • ๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• - ํ”„๋ก์‹œ ํŒจํ„ด, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค :)

 

 

 

๐ŸŽฏ  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• 1 - ํ”„๋ก์‹œ ํŒจํ„ด

ํ”„๋ก์‹œ(Proxy)

https://milkye.tistory.com/202

  • ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ํŒจํ„ด์˜ ํ•˜๋‚˜
  • ๋‹ค๋ฅธ ๋ฌด์–ธ๊ฐ€์™€ ์ด์–ด์ง€๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์—ญํ• ์„ ํ•˜๋Š” ํด๋ž˜์Šค
  • ์–ด๋–ค ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๋Š” ์šฉ๋„๋กœ ๋Œ€๋ฆฌ์ธ์ด๋‚˜ ๋Œ€๋ณ€์ธ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ„ด

 

https://fastcampus.co.kr/

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

 

 

ํ”„๋ก์‹œ ํŒจํ„ด์˜ ์ดํ•ด๋ฅผ ์œ„ํ•ด ๋กœ๊ทธ์ธ์„ ํ•˜๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๊ณ ๋ คํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์œ„ ์ƒํ™ฉ์—์„œ login() ๋ฉ”์†Œ๋“œ์—๋Š” ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜ ๋“ฑ๊ณผ ๊ฐ™์€ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ์—์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋‹ค๋ณด๋‹ˆ ์‘์ง‘๋„๋„ ๋‚ฎ์•„์ง€๊ฒŒ ๋˜๊ณ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋”๋ผ๋„ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ๋„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์ง€ ์•Š์€ ์ฝ”๋“œ๊ฐ€ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๋”๋ถˆ์–ด ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ๋„ ํฌํ•จ๋œ๋‹ค๋ฉด ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€์— ์˜์กดํ•˜๊ณ  ์žˆ์„ ํ™•๋ฅ ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด์„ฑ๋˜ํ•œ ๋†’์•„์ง€๊ฒŒ ๋˜๊ณ ,

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

๋˜ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์›์น™(SOLID) ์ค‘ ํ•˜๋‚˜์ธ ๋‹จ์ผ์ฑ…์ž„์›์น™(Single Responsibility Principle)์—๋„ ์–ด๊ธ‹๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์„ ํ”„๋ก์‹œ ํŒจํ„ด์„ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๊ตฌ์กฐ์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์ž…์žฅ์—์„œ๋Š” ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์•„๋ฌด๋Ÿฐ ์ฐจ์ด์ ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ํ”„๋ก์‹œ ํŒจํ„ด์— ์˜ํ•ด ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด ์ˆ˜ํ–‰๋˜๊ณ , ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

 

 

 

ํ”„๋ก์‹œ ํŒจํ„ด ์˜ˆ์ œ

@Getter
@Setter
public class Book {
    private String title;
}


/* ์„œ๋ธŒ์ ํŠธ ์—ญํ•  */
public interface BookService {
    void rent(Book book);
}

/* ํ”„๋ก์‹œ */
public class BookServiceProxy implements BookService {

    // ํ”„๋ก์‹œ๋Š” ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•จ(delegate ->)
    private final RealBookService realBookService;

    public BookServiceProxy(RealBookService realBookService) {
        this.realBookService = realBookService;
    }

    // ํ”„๋ก์‹œ์—์„œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€
    @Override
    public void rent(Book book) {
        System.out.println("ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ");
        realBookService.rent(book); // ํ”„๋ก์‹œ -> ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ
        System.out.println("๋กœ๊น…");
    }
}

/* ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ ์—ญํ•  */
@Service
public class RealBookService implements BookService {

    /*
     rent(): ์ฑ…์„ ๋นŒ๋ฆฌ๋Š”(ํ•ต์‹ฌ ๊ธฐ๋Šฅ) ๋ฉ”์†Œ๋“œ
     ์ฑ…์„ ๋นŒ๋ฆฌ๊ธฐ ์ „ ํ›„ ํŠธ๋žœ์žญ์…˜ & ๋กœ๊น…(๋ถ€๊ฐ€ ๊ธฐ๋Šฅ) ์ถ”๊ฐ€
    */
    public void rent(Book book) {
        System.out.println("rent: " + book.getTitle());
    }
}

/* ํด๋ผ์ด์–ธํŠธ */
public class Client {
    public static void main(String[] args) {
        BookService bookService = new BookServiceProxy(new RealBookService());
        bookService.rent(new Book());
    }
}


ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ
rent: null
๋กœ๊น…

 

์œ„ ์ฝ”๋“œ์™€ ์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋น„๊ตํ•ด๊ฐ€๋ฉฐ ํ™•์ธํ•˜์‹œ๋ฉด ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ๋” ์ˆ˜์›”ํ•ฉ๋‹ˆ๋‹ค :)

์œ„ ์˜ˆ์ œ์ฝ”๋“œ์—์„œ ๊ฐ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Client = Client
  • BookService = Subject
  • BookServiceProxy = Proxy
  • RealBookService = RealSubject

 

๋”ฐ๋ผ์„œ ํ”„๋ก์‹œ์˜ ์—ญํ• ์„ ํ•˜๋Š” BookServiceProxy๋Š” ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ์ธ RealBookService ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํ”„๋ก์‹œ๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ๋„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ธ ์ฑ…์„ ๋นŒ๋ฆฌ๋Š” ๊ธฐ๋Šฅ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ”„๋ก์‹œ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๋งŒ ๋‹ค์‹œ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

/* ํ”„๋ก์‹œ */
public class BookServiceProxy implements BookService {

    // ํ”„๋ก์‹œ๋Š” ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•จ(delegate ->)
    private final RealBookService realBookService;

    public BookServiceProxy(RealBookService realBookService) {
        this.realBookService = realBookService;
    }

    // ํ”„๋ก์‹œ์—์„œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€
    @Override
    public void rent(Book book) {
        System.out.println("ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ");
        realBookService.rent(book); // ํ”„๋ก์‹œ -> ๋ฆฌ์–ผ ์„œ๋ธŒ์ ํŠธ
        System.out.println("๋กœ๊น…");
    }
}

 

 

 

 

๐ŸŽฏ  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์œ„์ž„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ• 2 - ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์„ค๋ช…ํ•˜๊ธฐ ์ „์— ์™œ ํ•„์š”ํ•œ์ง€ ์ƒ์†์„ ํ†ตํ•œ ํ™•์žฅ๊ณผ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋‚ด๋น„๊ฒŒ์ด์…˜ SW์—์„œ ๋„๋กœ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์€ ๋„๋กœ๋ฅผ ๊ฐ„๋‹จํ•œ ์„ ์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด๊ณ , ๋‚ด๋น„๊ฒŒ์ด์…˜์— ๋”ฐ๋ผ ๋„๋กœ์˜ ์ฐจ์„ ์„ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์€

(์ถ”๊ฐ€์ ์œผ๋กœ) ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ ๋„๋กœ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ํด๋ž˜์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • RoadDisplay ํด๋ž˜์Šค: ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
  • RoadDisplayWithLane ํด๋ž˜์Šค: ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐจ์„ ์„ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต
public class RoadDisplay { // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ ๊ธฐ๋Šฅ
    public void draw() {
        System.out.println("๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ");
    }
}


public class RoadDisplayWithLane extends RoadDisplay { // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ

    @Override
    public void draw() {
        super.draw(); // ์ƒ์œ„ ํด๋ž˜์Šค(๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ)
        drawLine();   // ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐจ์„  ํ‘œ์‹œ
    }

    private void drawLine() {
        System.out.println("์ฐจ์„  ํ‘œ์‹œ");
    }
}


public class Client {
    public static void main(String[] args) {
        RoadDisplay road = new RoadDisplay();
        road.draw(); // ๊ธฐ๋ณธ ๋„๋กœ๋งŒ ํ‘œ์‹œ

        RoadDisplay roadWithLane = new RoadDisplayWithLane();
        roadWithLane.draw(); // ๊ธฐ๋ณธ ๋„๋กœ + ์ฐจ์„  ํ‘œ์‹œ
    }
}

๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
์ฐจ์„  ํ‘œ์‹œ

RoadDisplay ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ draw() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

RoadDisplayWithLane ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ ๋„๋กœ + ์ฐจ์„  ํ‘œ์‹œ๋ฅผ ์œ„ํ•ด ์ƒ์†๋ฐ›์€ draw() ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•ฉ๋‹ˆ๋‹ค.

 

 

๋ฌธ์ œ์ 

  • ์ฐจ์„  ํ‘œ์‹œ๊ฐ€ ์•„๋‹Œ ๋˜ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”? ex) ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
  • ๋‹ค์–‘ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์กฐํ•ฉํ•ด ์ œ๊ณตํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ex) ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ

์œ„ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด RoadDisplay ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ๊ตํ†ต๋Ÿ‰์„ ํ‘œ์‹œํ•˜๋Š” RoadDisplayWithTraffic ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

RoadDisplayWithTraffic ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ํ›„์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

// ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
public class RoadDisplayWithTraffic extends RoadDisplay {

    @Override
    public void draw() {
        super.draw(); // ์ƒ์œ„ ํด๋ž˜์Šค(๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ)
        drawTraffic(); // ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
    }

    private void drawTraffic() {
        System.out.println("๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ");
    }
}

RoadDisplay ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ๋„๋กœ ํ‘œ์‹œ์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ(์ฐจ์„  ํ‘œ์‹œ, ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ ๋“ฑ)์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์ ์ ˆํ•œ ์„ค๊ณ„ ๋ฐฉ๋ฒ•์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์˜ ์กฐํ•ฉ์„ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ƒ์†์„ ํ†ตํ•œ ํ™•์žฅ์€ ๊ฐ ๊ธฐ๋Šฅ๋ณ„ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ๋„๋กœ ํ‘œ์‹œ๋ฅผ ํ•˜๋Š” ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ ์ฐจ์„  ํ‘œ์‹œ, ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ, ๊ต์ฐจ๋กœ ํ‘œ์‹œ๋ฅผ 3๊ฐ€์ง€์˜ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํ–ˆ์„๋•Œ, ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด 8๊ฐ€์ง€์˜ ์กฐํ•ฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ฒฝ์šฐ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ
(๋„๋กœ ํ‘œ์‹œ)
์ถ”๊ฐ€ ๊ธฐ๋Šฅ ํด๋ž˜์Šค ์ด๋ฆ„
์ฐจ์„  ํ‘œ์‹œ ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ ๊ต์ฐจ๋กœ ํ‘œ์‹œ
1 O       RoadDisplay
2 O O     RoadDisplayWithLane
3 O   O   RoadDisplayWithTraffic
4 O     O RoadDisplayWithCrossing
5 O O O   RoadDisplayWithLaneTraffic
6 O O   O RoadDisplayWithLaneCrossing
7 O   O O RoadDisplayWithTrafficCrossing
8 O O O O RoadDisplayWithLaneTrafficCrossing

์œ„ ํ‘œ์™€ ๊ฐ™์ด ๊ฐ ์กฐํ•ฉ๋ณ„๋กœ RoadDisplay ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” 7๊ฐœ์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋” ํ™•์žฅํ•ด์„œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด n๊ฐœ๋ผ๋ฉด (2^n - 1)๊ฐœ์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์—„์ฒญ๋‚œ ์ž‘์—…์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

 

์ด์™€ ๊ฐ™์ด ์ƒ์†์„ ์ด์šฉํ•œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ถ”๊ฐ€๋˜๋Š” ๊ธฐ๋Šฅ์˜ ์กฐํ•ฉ๋ณ„๋กœ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์กฐํ•ฉ ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๋ณ„๋กœ ๊ฐœ๋ณ„์ ์ธ ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•˜๊ณ , ๊ธฐ๋Šฅ์„ ์กฐํ•ฉํ•  ๋•Œ ๊ฐ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ์กฐํ•ฉ์„ ์ด์šฉํ•จ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ํ†ตํ•ด ์œ„ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

โ€ป ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ผ์ด ์—†๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ์ƒ์†์œผ๋กœ ์„ค๊ณ„๋ฅผ ํ–ˆ๋”๋ผ๋„, ์‹ค์ œ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์€ ์–ด๋–ป๊ฒŒ ๋  ์ง€ ๋ชจ๋ฅด๋Š” ์ผ์ด๊ธฐ์— ์ฒ˜์Œ๋ถ€ํ„ฐ ์„ค๊ณ„๋ฅผ ์ œ๋Œ€๋กœ ํ•œ๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ์ƒ์† ํ™•์žฅ์˜ ๋ฌธ์ œ๋ฅผ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ƒ์† ๋ฐฉ์‹์˜ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๋ฌธ์ œ์  ํ•ด๊ฒฐ(๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด)

๊ธฐ๋ณธ ๊ธฐ๋Šฅ(๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ)๋งŒ ์ด์šฉํ•  ๋•Œ๋Š” RoadDisplay ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ฐจ์„ ์„ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€์ ์œผ๋กœ ํ•„์š”ํ•˜๋‹ค๋ฉด LaneDecorator ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋•Œ LaneDecorator์—์„œ๋Š” ์ฐจ์„  ํ‘œ์‹œ ๊ธฐ๋Šฅ๋งŒ ์ง์ ‘์ ์œผ๋กœ ์ œ๊ณตํ•˜๊ณ , ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ ๊ธฐ๋Šฅ์€ RoadDisplay ํด๋ž˜์Šค์˜ draw() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด LaneDecorator ํด๋ž˜์Šค๋Š” RoadDisplay ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํ•„์š”ํ•œ๋ฐ, ์ด๋ฅผ ์ƒ์œ„ ํด๋ž˜์Šค์ธ DisplayDecorator ํด๋ž˜์Šค์—์„œ Display ํด๋ž˜์Šค๋กœ์˜ ์ปดํฌ์ง€์…˜(composition) ๊ด€๊ณ„๋ฅผ ํ†ตํ•ด ํ‘œํ˜„๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

์œ„ ๋ฐฉ์‹์œผ๋กœ ์„ค๊ณ„๋œ ํด๋ž˜์Šค์˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public abstract class Display {
    public abstract void draw();
}


// ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
public class RoadDisplay extends Display {

    @Override
    public void draw() {
        System.out.println("๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ");
    }

}


// ๋‹ค์–‘ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๊ณตํ†ต ํด๋ž˜์Šค
public abstract class DisplayDecorator extends Display {
    private final Display decoratedDisplay;

    public DisplayDecorator(Display decoratedDisplay) {
        this.decoratedDisplay = decoratedDisplay;
    }

    public void draw() {
        decoratedDisplay.draw();
    }

}


// ์ฐจ์„  ํ‘œ์‹œ
public class LaneDecorator extends DisplayDecorator {
    
    // ๊ธฐ์กด ํ‘œ์‹œ ํด๋ž˜์Šค ์„ค์ •
    public LaneDecorator(Display decoratedDisplay) {
        super(decoratedDisplay);
    }
    
    public void draw() {
        super.draw(); // ์„ค์ •๋œ ๊ธฐ์กด ํ‘œ์‹œ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰
        drawLane();   // ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐจ์„  ํ‘œ์‹œ
    }

    private void drawLane() {
        System.out.println("\t์ฐจ์„  ํ‘œ์‹œ");
    }
}


// ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
public class TrafficDecorator extends DisplayDecorator {

    // ๊ธฐ์กด ํ‘œ์‹œ ํด๋ž˜์Šค ์„ค์ •
    public TrafficDecorator(Display decoratedDisplay) {
        super(decoratedDisplay);
    }

    public void draw() {
        super.draw(); // ์„ค์ •๋œ ๊ธฐ์กด ํ‘œ์‹œ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰
        drawTraffic();
    }

    private void drawTraffic() {
        System.out.println("\t๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ");
    }
}


// ํด๋ผ์ด์–ธํŠธ, new -> ๊ฐ์ฒด์™€์˜ ์กฐํ•ฉ
public class Client {
    public static void main(String[] args) {
        Display road = new RoadDisplay();
        road.draw(); // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ

        Display roadWithLane = new LaneDecorator(new RoadDisplay());
        roadWithLane.draw(); // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ

        Display roadWithTraffic = new TrafficDecorator(new RoadDisplay());
        roadWithTraffic.draw(); // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
        
        Display roadWithLaneAndTraffic = 
        	new TrafficDecorator(new LaneDecorator(new RoadDisplay()));
        roadWithLaneAndTraffic.draw(); // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
    }
}



๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ

๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
    ์ฐจ์„  ํ‘œ์‹œ
    
๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
    ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
    
๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
    ์ฐจ์„  ํ‘œ์‹œ
    ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ

์œ„ ์ฝ”๋“œ์—์„œ ์‚ดํŽด๋ณผ ์ ์€ road, roadWithLane, roadWithTraffic ๊ฐ์ฒด์˜ ์ ‘๊ทผ์ด ๋ชจ๋‘ Display ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง„๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

์ฆ‰ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์— ๊ด€๊ณ„์—†์ด Client ํด๋ž˜์Šค๋Š” ๋ชจ๋‘ Display ํด๋ž˜์Šค๋งŒ์„ ํ†ตํ•ด ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋„๋กœ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • road: ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
  • roadWithLane: ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ
  • roadWithTraffic: ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
  • roadWithLaneAndTraffic: ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ

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

์ด๋Ÿฌํ•œ ์„ค๊ณ„๋Š” ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์˜ ์ˆ˜๊ฐ€ ๋งŽ์„์ˆ˜๋ก ์กฐํ•ฉ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๋„ ๋งŽ์•„์ง€๋ฏ€๋กœ ํšจ๊ณผ๊ฐ€ ํฝ๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ์ฐจ์„  ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ์˜ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์— ๊ต์ฐจ๋กœ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ ์•„๋ž˜ UML๊ณผ ๊ฐ™์ด ๋‹จ์ˆœํžˆ CrossingDecorator ํด๋ž˜์Šค๋งŒ ์ถ”๊ฐ€ํ•œ ํ›„ ๊ฐ์ฒด์™€์˜ ์กฐํ•ฉ์„ ํ†ตํ•ด ์ ์šฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๊ต์ฐจ๋กœ ํ‘œ์‹œ
public class CrossingDecorator extends DisplayDecorator {
    
    // ๊ธฐ์กด ํ‘œ์‹œ ํด๋ž˜์Šค ์„ค์ •
    public CrossingDecorator(Display decoratedDisplay) {
        super(decoratedDisplay);
    }
    
    public void draw() {
        super.draw();   // ์„ค์ •๋œ ๊ธฐ์กด์˜ ํ‘œ์‹œ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰
        drawCrossing(); // ์ถ”๊ฐ€์ ์œผ๋กœ ๊ต์ฐจ๋กœ ํ‘œ์‹œ
    }

    private void drawCrossing() {
        System.out.println("\t๊ต์ฐจ๋กœ ํ‘œ์‹œ");
    }

}


// ํด๋ผ์ด์–ธํŠธ
public class Client {
    ...
    
    // new ...(new ...(new ...( -> ๊ฐ์ฒด ์กฐํ•ฉ
    Display roadWithCrossingAndLandAndTraffic
        = new LaneDecorator(new TrafficDecorator(new CrossingDecorator(new RoadDisplay())));
    roadWithCrossingAndLandAndTraffic.draw(); // ๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ + ์ฐจ์„  ํ‘œ์‹œ + ๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ + ๊ต์ฐจ๋กœ ํ‘œ์‹œ
}


๊ธฐ๋ณธ ๋„๋กœ ํ‘œ์‹œ
	๊ต์ฐจ๋กœ ํ‘œ์‹œ
	๊ตํ†ต๋Ÿ‰ ํ‘œ์‹œ
	์ฐจ์„  ํ‘œ์‹œ

 

 

 

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(Decorator) ํŒจํ„ด

  • ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์˜ ์ข…๋ฅ˜๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ ๊ฐ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ Decorator ํด๋ž˜์Šค๋กœ ์ •์˜ํ•œ ํ›„ ํ•„์š”ํ•œ Decorator ๊ฐ์ฒด๋ฅผ ์กฐํ•ฉํ•จ์œผ๋กœ์จ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์˜ ์กฐํ•ฉ์„ ์„ค๊ณ„
  • ์ฃผ์–ด์ง„ ์ƒํ™ฉ ๋ฐ ์šฉ๋„์— ๋”ฐ๋ผ ์–ด๋–ค ๊ฐ์ฒด์— ์ฑ…์ž„์„ ๋ง๋ถ™์ด๋Š” ํŒจํ„ด
  • ๊ธฐ๋Šฅ ํ™•์žฅ์ด ํ•„์š”ํ•  ๋•Œ ์„œ๋ธŒํด๋ž˜์Šค ๋Œ€์‹  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐํ•œ ๋Œ€์•ˆ์ด ๋  ์ˆ˜ ์žˆ์Œ
  • ์•ž์œผ๋กœ์˜ ๋ณ€๊ฒฝ์ด ์–ผ๋งˆ๋‚˜ ๋ ์ง€ ๋ชจ๋ฅด๋Š” ์ƒํ™ฉ์—์„œ ์ƒ์†์„ ์‚ฌ์šฉํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜์ง€ ๋ชปํ•จ

 

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ UML์ž…๋‹ˆ๋‹ค.

  • Component: ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๋œปํ•˜๋Š” ConcreteComponent์™€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๋œปํ•˜๋Š” Decorator์˜ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ •์˜, ์ฆ‰ ํด๋ผ์ด์–ธํŠธ๋Š” Component๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉ
  • ConcreteComponent: ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค
  • Decorator: ๋งŽ์€ ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ Decorator์˜ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ œ๊ณต
  • ConcreteDecoratorA, ConcreteDecoratorB: Decorator์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€๋˜๋Š” ๊ฐœ๋ณ„์ ์ธ ๊ธฐ๋Šฅ

 

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.

ConcreteComponent๊ฐ€ c๋กœ ์ •์˜๋˜์–ด ์žˆ๊ณ , ConcreteDecoratorA์˜ ๊ฐ์ฒด a์™€ ์ด์— ๋Œ€ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ConcreteDecoratorB์˜ ๊ฐ์ฒด b๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ณ˜์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

Component c = new ConcreteComponent();
Component a = new ConcreteDecoratorA(c);
Component b = new ConcreteDecoratorB(a);

์œ„ ์ฝ”๋“œ์—์„œ Client๊ฐ€ ๊ฐ์ฒด b์˜ operation ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด b๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” Component, ์ฆ‰ ConcreteDecoratorA ๊ฐ์ฒด a์˜ operation ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด a ์—ญ์‹œ ์ž์‹ ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” Component, ์ฆ‰ ConcreteComponent ๊ฐ์ฒด c์˜ operation ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ํ›„ ์ž์‹ ์˜ addedBehavior ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด b ์—ญ์‹œ ๊ฐ์ฒด a์˜ operation ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ํ›„ ์ž์‹ ์˜ addedBehavior ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

 

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

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

 

๊ฐœ์ธ์ ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ๊ฒฝ์šฐ ์ดํ•ดํ•˜๊ธฐ๊นŒ์ง€ ๋ช‡ ๋ฒˆ์„ ๊ณ„์†ํ•ด์„œ ๋ณด์•˜๋Š”๋ฐ, ์™„์ „ํžˆ ์ดํ•ด๋ฅผ ํ–ˆ๋‹ค๊ณ ๋Š” ๋ณด๊ธฐ ํž˜๋“ค๊ฒ ์ง€๋งŒ ๊ณ„์† ๋ณด๋‹ค๋ณด๋‹ˆ ๋Œ€๋žต์ ์œผ๋กœ๋‚˜๋งˆ ์ดํ•ด๊ฐ€ ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ด๋ ‡๊ฒŒ ์ •๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ, ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์‹ค์ œ ์ ์šฉ์„ ํ•ด ๋ณด๋Š” ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์— ์‹ค๋ฌด์—์„œ ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ์ ์šฉํ•ด๋ณด๊ณ , ๊ฒฝํ—˜์„ ํ†ตํ•ด ์ œ ๊ฒƒ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค :)

๊ทธ ๋•Œ ๊ธฐํšŒ๊ฐ€ ๋œ๋‹ค๋ฉด, ๋‹ค์‹œ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

AOP๊นŒ์ง€ ์ •๋ฆฌ๋ฅผ ํ•˜๊ธฐ์—” ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๋ฐฉ๋Œ€ํ•ด์งˆ ๊ฒƒ ๊ฐ™์•„ AOP์— ๋Œ€ํ•œ ์ •๋ฆฌ๋Š” ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿคฃ

 

 

 

 

References

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€