bhlee chapter 07 Behavior - JAVACAFE-STUDY/2019-implementation-patterns GitHub Wiki

์ถœ์ฒ˜: ์ผ„ํŠธ๋ฒก์˜ ๊ตฌํ˜„ํŒจํ„ด 7์žฅ ํ–‰์œ„

์ปดํ“จํ„ฐ๋Š” ๋ช…๋ น์–ด๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ์ˆ˜ํ–‰ํ•œ๋‹ค.
์ด๋Ÿฌํ•œ ํ”„๋กœ๊ทธ๋žจ์˜ ํ–‰์œ„(Behavior)๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.

์ œ์–ด ํ๋ฆ„(Control Flow)

  • ์กฐ๊ฑด๋ฌธ์„ ์‚ฌ์šฉํ•ด ํŠน์ • ์ƒํƒœ์—์„œ๋งŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ธŒ๋ฃจํ‹ด์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•ด ํ˜„์žฌ ํ๋ฆ„์„ ๋ฒ—์–ด๋‚˜(pop) ์ด์ „ ์Šคํƒ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์š” ํ๋ฆ„(Main Flow)

  • ํ”„๋กœ๊ทธ๋žจ์˜ ๊ณผ์ •์ด ์–ด๋””์„œ ์‹œ์ž‘ํ•˜๊ณ  ์–ด๋””์„œ ๋๋‚˜๋Š”์ง€์— ๋Œ€ํ•œ ์ฃผ์š” ํ๋ฆ„์„ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•ด์•ผํ•œ๋‹ค.

  • ํ”์น˜ ์•Š์€ ์ƒํ™ฉ์ด๋‚˜ ์—๋Ÿฌ ์ƒํ™ฉ์€ ์˜ˆ์™ธ์™€ ์กฐ๊ฑด์ ˆ์„ ์‚ฌ์šฉํ•ด์„œ ํ‘œํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

๋ฉ”์‹œ์ง€(Message)

  • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ข‹์€ ์  ์ค‘ ํ•˜๋‚˜๋Š” ๊ฐ™์€ ํ”„๋กœ์‹œ์ €๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋” ํ’๋ถ€ํ•œ ๋‚ด์šฉ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฒƒ์ด๋‹ค.

  • ์•„๋ž˜ ์ฝ”๋“œ๋Š” **"์—ฐ์‚ฐ ๊ณผ์ •์€ 3๋‹จ๊ณ„์ด๋ฉฐ, ์ง€๊ธˆ ๋‹น์žฅ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์•Œ ํ•„์š”๋Š” ์—†๋‹ค"**๋Š” ๋œป์„ ๊ฐ–๊ณ  ์žˆ๋‹ค.

    compute() {
        input();
        process();
        output();
    }
    
  • ๋ฉ”์‹œ์ง€๋ฅผ ์ œ์–ด ํ๋ฆ„์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์ƒํƒœ์˜ ๋ณ€ํ™”๊ฐ€ ์ค‘์š”ํ•ด์ง„๋‹ค.

์„ ํƒ ๋ฉ”์‹œ์ง€(Choosing Message)

  • ์•„๋ž˜์™€ ๋‹คํ˜•์  ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ช…์‹œ์  ์กฐ๊ฑด๋ฌธ์˜ ์‚ฌ์šฉ์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ถ”ํ›„ ํ™•์žฅ์ด ์‰ฝ๋‹ค.

    public void displayShape(Shape subject, Brush brush) {
        brush.display(subject);
    }
    
  • ์œ„์™€ ๊ฐ™์ด ์„ ํƒ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ์ฝ”๋“œ๋ฅผ ์ฝ์„ ๋•Œ ์—ฐ์‚ฐ์˜ ์„ธ๋ถ€ ๊ตฌํ˜„์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ์‚ดํŽด๋ด์•ผ ํ•œ๋‹ค.

๋”๋ธ” ๋””์ŠคํŒจ์น˜(Double Dispatch)

  • ์„ ํƒ ๋ฉ”์‹œ์ง€๊ฐ€ ์ผ์ฐจ์›์  ๋ณ€ํ˜•์— ์ ํ•ฉํ•œ๋ฐ,
    ๋‘ ๊ฐ€์ง€์˜ ๋…๋ฆฝ์ ์ธ ์ฐจ์›์—์„œ์˜ ๋ณ€ํ˜•์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” 2๊ฐœ์˜ ์„ ํƒ ๋ฉ”์‹œ์ง€๋ฅผ ์ง๋ ฌ๋กœ ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

    <script src="https://gist.github.com/libliboom/4abf138ef543a44e90a8cc5a22525ecc.js"></script>

๋ถ„๋ฆฌ(์ˆœ์ฐจ) ๋ฉ”์‹œ์ง€(Decomposing Message)

  • ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋œ ๋ณต์žกํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ๋‹ค๋ฉด, ๊ด€๋ จ๋œ ๋‹จ๊ณ„๋“ค์„ ๋ชจ์œผ๊ณ  ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฉ”์‹œ์ง€์˜ ๋ชฉ์ ์€ ๊ตฌํ˜„์ด ์•„๋‹Œ, ํ•จ์ˆ˜๋ฅผ ๋‚˜๋ˆˆ ๋’ค ๊ทธ ๋‚˜๋ˆ„์–ด์ง„ ์ผ๋ถ€ ํ•ญ๋ชฉ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ์ผ๋ฟ์ด๋‹ค.

  • ๋ถ„๋ฆฌ๋œ ๋ฉ”์„ธ์ง€์˜ ์ด๋ฆ„์€ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ์ด๋ฆ„๋งŒ์œผ๋กœ ์ดํ›„ ๋‹จ๊ณ„์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ์ง€์–ด์•ผ ํ•œ๋‹ค.

๋˜๋Œ๋ฆผ ๋ฉ”์‹œ์ง€(Reversing Message)

  • ์•„๋ž˜์™€ ๊ฐ™์ด ๋Œ€์นญ์„ฑ์„ ์ด์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

    void compute() {
        input();
        process(helper); // vs helper.process(this);
        output();
    }
    
    void process(Helper helper) {
        helper.process(this);
    }
    
  • ๋Œ€์นญ์„ฑ๊ณผ ๊ฐ™์€ "๋ฏธํ•™์ "์ธ ์š”์†Œ๋Š” ์ฝ”๋“œ ํŒจํ„ด ๋งŒํผ์ด๋‚˜ ์ฝ”๋“œ ํ’ˆ์งˆ์— ํ–ฅ์ƒ์„ ๋„๋ชจํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ์š”์†Œ์ด๋‹ค.

์ดˆ์ฒญ ๋ฉ”์‹œ์ง€(Inviting Message)

  • ํ•˜์œ„ํด๋ž˜์Šค์˜ ์–ด๋–ค ์—ฐ์‚ฐ์„ ๋ณ€ํ˜•์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ์„ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์ ๋‹นํ•œ ์ด๋ฆ„์˜ ๋ฉ”์‹œ์ง€๋กœ ์•Œ๋ ค์ฃผ๋Š”๊ฒƒ์ด ์ข‹๋‹ค. (jdk or sdk ์˜ˆ์ œ ์ฐพ์•„ ๋ณด๊ธฐ)

  • ์ด๋ฆ„์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณ€ํ˜• ๊ฐ€๋Šฅ์„ฑ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด ์ถ”์ƒ ๋ฉ”์†Œ๋“œ ์„ ์–ธ์„ ๊ณ ๋ คํ•ด์•ผํ•œ๋‹ค.

์„ค๋ช… ๋ฉ”์‹œ์ง€(Explaning Message)

  • ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์—์„œ ๊ฐœ๋ฐœ์ž์˜ ์˜๋„์™€ ๊ตฌํ˜„์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์€ ์–ธ์ œ๋‚˜ ์ค‘์š”ํ•˜๋‹ค.

  • ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ์ค„๋กœ ๋œ ์ฝ”๋“œ์— ์ฃผ์„์„ ๋ถ™์ด๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ, ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ์œ„ํ•ด ์„ค๋ช… ๋ฉ”์‹œ์ง€ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.

    // example
    flags |= LOADED_BIT; // ๋กœ๋“œ ๋น„ํŠธ๋ฅผ ์„ค์ •
    
    // recommend
    setLoadedFlag();
    

์˜ˆ์™ธ ํ๋ฆ„(Exceptional Flow)

  • ์˜ˆ์™ธ ํ๋ฆ„์€ ์ฃผ์š” ํ๋ฆ„์˜ ๋ช…๋ฃŒ์„ฑ์„ ํ›ผ์†ํ•˜์ง€ ์•Š๋Š” ๋ฒ”์œ„ ๋‚ด์—์„œ ์กฐ๊ฑด์ ˆ์ด๋‚˜ ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•ด ํ‘œํ˜„ํ•œ๋‹ค.

  • ๋‹ค์–‘ํ•œ ์ˆ˜ํ–‰ ๊ฒฝ๋กœ๋ฅผ ๋™๋“ฑํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์— ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋‚œ๋ฌดํ•˜๊ณ  ํŠน๋ณ„ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„ ๊ฐ’๋“ค์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

๋ณดํ˜ธ์ ˆ(Guard Clause)

  • ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณดํ˜ธ์ ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•œ ์ง€์—ญ์  ์˜ˆ์™ธ ์ƒํ™ฉ์„ ์ง€์—ญ์ ์ธ ๋ณ€ํ™”๋งŒ์„ ์ˆ˜๋ฐ˜ํ•˜๋ฉฐ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

    void initialize() {
        if(!isInitialized()) {
            ... // then ์— ํ•ด๋‹น ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ
        }
    
        // else ์กฐ๊ฑด์„ ์ฐพ๊ฒŒ ๋œ๋‹ค.
    }
    
    void initialize() {
        if(isInitialized())
            return ; // ์ดˆ๊ธฐํ™”๊ฐ€ ๋œ ๊ฒฝ์šฐ
    
        // ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 
        //   (์ดˆ๊ธฐํ™” ๋ฉ”์†Œ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœ๋˜๋„ ์‹ค์ œ ์ดˆ๊ธฐํ™”๋Š” ๋‹จ ํ•œ๋ฒˆ๋งŒ ์ˆ˜ํ–‰)
        //   (์ดˆ๊ธฐํ™”๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ œ์–ด ํ๋ฆ„์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•˜๋Š” ๊ฒฝ์šฐ)
    }
    
  • if-then-else๋Š” ๋™๋“ฑํ•œ ์ค‘์š”์„ฑ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ์ œ์–ด ํ๋ฆ„์„ ํ‘œํ˜„ํ•œ๋‹ค.

  • ๋ณดํ˜ธ์ ˆ์€ ํ•œ ์ชฝ์˜ ์ œ์–ด ํ๋ฆ„์ด ๋‹ค๋ฅธ ์ชฝ๋ณด๋‹ค ์ค‘์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค.

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ์กฐ๊ฑด์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ณดํ˜ธ์ ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ์ œ์–ด ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

    <script src="https://gist.github.com/libliboom/d7d7f24b759e608f130bc96488c29934.js"></script> <script src="https://gist.github.com/libliboom/b11e7c1ac6079ae1299a4d1ab3e6b2c5.js"></script>

์˜ˆ์™ธ(Exception)

  • ์Šคํƒ ์ƒ์—์„œ ํ•œ์ฐธ ์œ„์ชฝ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด(๋””์Šคํฌ๊ฐ€ ๊ฐ€๋“์ฐจ๊ฑฐ๋‚˜ ๋„คํŠธ์› ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ๊ฒฝ์šฐ) ์ด๋Ÿฐ ๋ฌธ์ œ๋Š” ์Šคํƒ์˜ ํ•œ์ฐธ ์•„๋ž˜์ชฝ์—์„œ ํ•ด๊ฒฐํ•˜๋Š”๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๋‹ค.

  • ์˜ˆ์™ธ๋ฅผ ๋ฐœ๊ฒฌํ•œ ์ชฝ์—์„œ๋Š” ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ณ , ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ชฝ์—์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐ›๋Š” ํŽธ์ด ๊ทธ ์‚ฌ์ด์˜ ๋ชจ๋“  ์ฝ”๋“œ์—์„œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋„ ๋ชปํ•˜๋ฉด์„œ ์˜ˆ์™ธ๋ฅผ ์ฒดํฌํ•˜๊ณ  ์ „๋‹ฌํ•˜๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ง€์ €๋ถ„ํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ํ›จ์”ฌ ๋‚ซ๋‹ค. (์ฝ”๋“œ ์˜ˆ์ œ ์ฐพ์•„๋ณด๊ธฐ)

  • ์กฐ๊ฑด์ ˆ๊ณผ ๋ฉ”์‹œ์ง€๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์˜ˆ์™ธ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋‹จ์ˆœ ์ œ์–ด ํ๋ฆ„ ๊ตฌ์กฐ ์ด์™ธ์— ์–ด๋–ค ์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€ ์•Œ์•„๋‚ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ์–ด๋ ต๋‹ค.

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

์ฒดํฌ ์˜ˆ์™ธ(Checked Exception)

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

  • Checked ์˜ˆ์™ธ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ฒดํฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์˜ˆ์™ธ๋ฅผ ๋ฐ›๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ ๋…๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.

์˜ˆ์™ธ ์ „๋‹ฌ(Exception Propagation)

  • ํ•˜์œ„ ์ˆ˜์ค€์˜ ์˜ˆ์™ธ๋Š” ๋ฌธ์ œ๋ฅผ ์ง„๋‹จํ•˜๋Š”๋ฐ ์œ ์šฉํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ๋–„๋ฌธ์— ํ•˜์œ„ ์ˆ˜์ค€ ์˜ˆ์™ธ๋ฅผ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ๋„์›€๋˜๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ์œ„ ์ˆ˜์ค€ ์˜ˆ์™ธ๋กœ ํฌ์žฅํ•ด ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค. (์ฝ”๋“œ ์˜ˆ์ œ ์ฐพ์•„๋ณด๊ธฐ)
โš ๏ธ **GitHub.com Fallback** โš ๏ธ