Post

๐Ÿน 10. Object Oriented Design

07. ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„

[ ์ ‘๊ทผ๋ฒ• ]

๋‹จ๊ณ„ #1: ๋ชจํ˜ธ์„ฑ์˜ ํ•ด์†Œ

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

๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์— ๊ด€ํ•œ ์งˆ๋ฌธ์„ ๋ฐ›์œผ๋ฉด, ์•„๋ž˜์— ๋Œ€ํ•œ ์งˆ๋ฌธ์„ ๋˜์ ธ์•ผ ํ•œ๋‹ค.

โ†’ ๋ˆ„๊ฐ€ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ฉฐ

โ†’ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€

์งˆ๋ฌธ์— ๋”ฐ๋ผ์„œ๋Š” ์œกํ•˜์›์น™์— ๋”ฐ๋ฅธ ์งˆ๋ฌธ์„ ๋˜์ ธ์•ผ ํ•  ๋•Œ๋„ ์žˆ๋‹ค. ๋ˆ„๊ฐ€, ๋ฌด์—‡์„, ์–ด๋””์„œ, ์–ธ์ œ, ์–ด๋–ป๊ฒŒ, ์™œ.

ex) ์ปคํ”ผ ๋ฉ”์ด์ปค์— ๋Œ€ํ•œ ๊ฐ์ฒด ์ง€ํ–ฅ์  ์„ค๊ณ„๋ฅผ ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.

์ปคํ”ผ ๋ฉ”์ด์ปค๋Š” ์‹œ๊ฐ„๋‹น ์ˆ˜๋ฐฑ ๋ช…์˜ ๊ณ ๊ฐ์„ ์ƒ๋Œ€ํ•˜๋ฉฐ ์—ด ๊ฐ€์ง€ ์ด์ƒ์˜ ์ œํ’ˆ์„ ๋งŒ๋“ค์–ด ๋‚ด์•ผ ํ•˜๋Š”, ๋Œ€๊ทœ๋ชจ ์‹๋‹น์— ์„ค์น˜๋˜๋Š” ๊ธฐ๊ณ„์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ํ˜น์€ ๋‚˜์ด ๋“œ์‹  ๋ถ„๋“ค์ด ์‚ฌ์šฉํ•˜๋Š”, ๋ธ”๋ž™ ์ปคํ”ผ๋งŒ ๋งŒ๋“œ๋Š” ๊ฐ„๋‹จํ•œ ๊ธฐ๊ณ„์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ์–ด๋–ค ์šฉ๋„๋กœ ์“ฐ์ด๋Š๋ƒ์— ๋”ฐ๋ผ ์„ค๊ณ„ ์ž์ฒด๊ฐ€ ์™„์ „ํžˆ ๋’ค๋ฐ”๋€๋‹ค.

๋‹จ๊ณ„ #2: ํ•ต์‹ฌ ๊ฐ์ฒด์˜ ์„ค๊ณ„

์ด์ œ ๋ฌด์—‡์„ ์„ค๊ณ„ํ•  ๊ฒƒ์ธ์ง€ ์ดํ•ดํ–ˆ์œผ๋‹ˆ, ์‹œ์Šคํ…œ์— ๋„ฃ์„ โ€˜ํ•ต์‹ฌ ๊ฐ์ฒดโ€™(core object)๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ฐํ•ด ๋ด์•ผ ํ•œ๋‹ค.

ex) ์‹๋‹น์„ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์œผ๋กœ ์„ค๊ณ„ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.

์ด๋•Œ ํ•ต์‹ฌ ๊ฐ์ฒด๋กœ๋Š” Table, Guest, Party, Order, Meal, Employee, Server, Host ๋“ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

๋‹จ๊ณ„ #3: ๊ด€๊ณ„ ๋ถ„์„

ํ•ต์‹ฌ ๊ฐ์ฒด๋ฅผ ์–ด๋Š ์ •๋„ ๊ฒฐ์ • ํ–ˆ๋‹ค๋ฉด, ์ด์ œ ๊ฐ์ฒด ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ๋ถ„์„ํ•ด์•ผ ํ•œ๋‹ค.

โ†’ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ๊ฐ์ฒด์— ์†ํ•ด ์žˆ๋Š”๊ฐ€(member)?

โ†’ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ์ƒ์†(inherit) ๋ฐ›์•„์•ผ ํ•˜๋Š” ๊ฐ์ฒด๋Š” ์žˆ๋‚˜?

โ†’ ๊ด€๊ณ„๋Š” ๋‹ค-๋Œ€-๋‹ค(many-to-many) ๊ด€๊ณ„์ธ๊ฐ€ ์•„๋‹ˆ๋ฉด ์ผ-๋Œ€-๋‹ค(one-to-many) ๊ด€๊ณ„์ธ๊ฐ€?

๊ฐ€๋ น, ์‹๋‹น ๋ฌธ์ œ์—์„  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๊ณ„ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • Party๋Š” Guests ๋ฐฐ์—ด์„ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • Server์™€ Host๋Š” Employee๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
  • ๊ฐ Table์€ Party๋ฅผ ํ•˜๋‚˜๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐ Party๋Š” Tables๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • Restaurant์— Host๋Š” ํ•œ ๋ช… ๋ฟ์ด๋‹ค.

์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ์€, ์ข…์ข… ์ž˜๋ชป๋œ ๊ฐ€์ •์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ•˜๋‚˜์˜ Table์— ์—ฌ๋Ÿฌ Party๊ฐ€ ์•‰๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค(์š”์ฆ˜ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ๋Œ€ํ˜• ๊ณต๋™ ํ…Œ์ด๋ธ”(communal table)์ด ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์ด๋‹ค). ์„ค๊ณ„๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ผ๋ฐ˜์ ์ด์–ด์•ผ ํ•˜๋Š”์ง€์— ๊ด€ํ•ด์„œ๋Š” ๋ฉด์ ‘๊ด€๊ณผ ์ƒ์˜ํ•œ ํ›„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๋‹จ๊ณ„ #4: ํ–‰๋™ ๋ถ„์„

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

ex) ํ•œ Party๊ฐ€ Restaurant์— ์ž…์žฅํ•˜๊ณ , ํ•œ Guest๊ฐ€ Host์—๊ฒŒ Table์„ ๋ถ€ํƒํ•œ ๊ฒฝ์šฐ

Host๋Š” Reservation์„ ์‚ดํŽด๋ณธ ๋‹ค์Œ ์ž๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น Party์—๊ฒŒ Table์„ ๋ฐฐ์ •ํ•  ๊ฒƒ์ด๋‹ค. ์ž๋ฆฌ๊ฐ€ ์—†๋‹ค๋ฉด Party๋Š” Reservation ๋ฆฌ์ŠคํŠธ ๋งจ ๋งˆ์ง€๋ง‰์— ์ถ”๊ฐ€๋  ๊ฒƒ์ด๋‹ค. ํ•œ Party๊ฐ€ ์‹์‚ฌ๋ฅผ ๋งˆ์น˜๊ณ  ๋– ๋‚˜๋ฉด ํ•œ Table์ด ๋น„๊ฒŒ ๋˜๊ณ , ๊ทธ ํ…Œ์ด๋ธ”์€ ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์œ„ Party์—๊ฒŒ ํ• ๋‹น๋  ๊ฒƒ์ด๋‹ค.

[ ๋””์ž์ธ ํŒจํ„ด ]

์‹ฑ๊ธ€ํ†ค(singleton)์ด๋‚˜ ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ(factory method)์™€ ๊ฐ™์€ ๋””์ž์ธ ํŒจํ„ด์„ ์‚ดํŽด๋ณธ๋‹ค.

๊ณ„์†ํ•ด์„œ ํŠน์ • ๋ฌธ์ œ์— โ€˜๊ฐ€์žฅโ€™ ์ ํ•ฉํ•œ ๋””์ž์ธ ํŒจํ„ด์„ ์ฐพ์œผ๋ ค๋Š” ํ•จ์ •์— ๋น ์ง€์ง€ ์•Š๋„๋ก ์กฐ์‹ฌํ•˜๋ผ. ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ทธ ๋ฌธ์ œ์— ์ ํ•ฉํ•œ ๋””์ž์ธ์„ ์ง์ ‘ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค. ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ํŒจํ„ด์ด ์ ํ•ฉํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.

์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค(singleton class)

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด(singleton pattern)

์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ์˜ค์ง ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ์„ ๊ฐ–๋„๋ก ํ•˜๋ฉฐ, ํ”„๋กœ๊ทธ๋žจ ์ „๋ฐ˜์— ๊ฑธ์ณ ๊ทธ ๊ฐ์ฒด ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ๋˜๋„๋ก ๋ณด์žฅ

โ†’ ์ •ํ™•ํžˆ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š” ์ „์—ญ ๊ฐ์ฒด(global object)๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ํŠนํžˆ ์œ ์šฉ

ex) Restaurant ํด๋ž˜์Šค๋Š” ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ๊ฐ–๋„๋ก ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

1
2
3
4
5
6
7
8
9
10
public class Restaurant {
    private static Restaurant _instance = null;
    protected Restaurant() { ... }
    public static Restaurant getInstance() {
        if (_instance == null) {
            _instance = new Restaurant();
        }
        return _instance;
    }
}

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์‹ฑ๊ธ€ํ†ค ๋””์ž์ธ ํŒจํ„ด์„ ์ข‹์•„ํ•˜์ง€ ์•Š๊ณ  ์‹ฌ์ง€์–ด โ€˜์•ˆํ‹ฐ-ํŒจํ„ดโ€™์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค. ์‹ฑ๊ธ€ํ†ค์„ ์‹ซ์–ดํ•˜๋Š” ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ์‹ฑ๊ธ€ํ†ค์ด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(unit test)์— ๋ฐฉํ•ด๋˜๋Š” ์š”์ธ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ(factory method)

ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ

์–ด๋–ค ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋˜, ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ• ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์คŒ

  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•
    • 1๋ฒˆ์งธ: Factory ๋ฉ”์„œ๋“œ ์ž์ฒด์— ๋Œ€ํ•œ ๊ตฌํ˜„์€ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ ํด๋ž˜์Šค๋ฅผ abstract๋กœ ์„ ์–ธํ•˜๊ณ  ๋†”๋‘๋Š” ๊ฒƒ
    • 2๋ฒˆ์งธ: Factory ๋ฉ”์„œ๋“œ๋ฅผ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•œ Creator ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ. ์ด ๊ฒฝ์šฐ์—๋Š” Factory ๋ฉ”์„œ๋“œ์— ์ƒ์„ฑํ•ด์•ผ ํ•  ํด๋ž˜์Šค๋ฅผ ์ธ์ž๋กœ ๋„˜๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      public class CardGame {
          public static CardGame createCardGame(GameType type) {
              if (type == GameType.Poker) {
                  return new PockerGame();
              } else if (type == GameType.BlackJack) {
                  return new BlackJackGame();
              }
              return null;
          }
      }
    
This post is licensed under CC BY 4.0 by the author.