๐Ÿ“Œ ์ „๋žตํŒจํ„ด


if - else์˜ ๋ฌธ์ œ์ 

example

public double calculate(boolean isFirstGuest, boolean isLastGuest, List<Item> items) {
  double sum = 0;
  for (Item item : items) {
    if (isFirstGuest) {
      sum += item.getPrice() * 0.9;
    } else if (!item.isFresh()) {
      sum += item.getPrice() * 0.8;
    } else if (isFirstGuest) {
      sum += item.getPrice() * 0.8;
    } else {
      sum += item.getPrice();
    }
  }
  return sum;
}

๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋  ๊ฒฝ์šฐ

  • ์ƒˆ๋กœ์šด ์กฐ๊ฑด๋ฌธ์„ ์ง์ ‘ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ๋•Œ๋ฌธ์— ์ถ”๊ฐ€๋˜๋Š” ๊ธฐ๋Šฅ๋“ค์ด ๋งŽ์•„์งˆ ์ˆ˜๋กฃ ์ฝ”๋“œ ๋ธ”๋Ÿญ๋„ ์ ์  ์ฆ๊ฐ€ํ•œ๋‹ค.
  • ์ด๋Ÿด ๊ฒฝ์šฐ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

๋ˆ„๋ฝ๋  ์œ„ํ—˜

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

๋•Œ๋ฌธ์— if-else๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.


OCP - Open Close Principle (๊ฐœ๋ฐฉ ํ์‡„์˜ ์›์น™)

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

์ ์šฉ ๋ฐฉ๋ฒ•

  • ์ƒ์†(is-a)
  • ์ปดํฌ์ง€์…˜(has-a)

์ปดํฌ์ง€์…˜

๋ณ€๊ฒฝ(ํ™•์žฅ)๋  ๊ฒƒ๊ณผ ๋ณ€ํ•˜์ง€ ์•Š์„ ๊ฒƒ์„ ๊ตฌ๋ถ„ํ•œ๋‹ค.

์ด ๋‘ ๋ชจ๋“ˆ์ด ๋งŒ๋‚˜๋Š” ์ง€์ ์— ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.

๊ตฌํ˜„์— ์˜์กดํ•˜๊ธฐ๋ณด๋‹ค ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

์˜ˆ์‹œ

  • List์™€ ArrayList์˜ ๊ด€๊ณ„
    • ํƒ€์ž… ์„ ์–ธ์€ List์ด์ง€๋งŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ๊ทธ ๊ตฌํ˜„์ฒด์ธ ArrayList๋กœ ์ƒ์„ฑํ•œ๋‹ค.

์ „๋žต ํŒจํ„ด

  • ๋””์ž์ธ ํŒจํ„ด ์ค‘ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ž„
    • ๋””์ž์ธ ํŒจํ„ด์ด๋ž€? (์†Œํ”„ํŠธ์›จ์–ด) ๋””์ž์ธ + (๊ณตํ†ต์ ์œผ๋กœ ๋งˆ์ฃผ์น˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์˜) ํŒจํ„ด
  • ๋™์ ์œผ๋กœ ์ „๋žต ์ˆ˜์ • ๊ฐ€๋Šฅ
  • ํ–‰์œ„๋ฅผ ํด๋ž˜์Šค๋กœ ์บก์Šํ™”ํ•ด ๋™์ ์œผ๋กœ ํ–‰์œ„๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์˜ ์ถ”๊ฐ€๊ฐ€ ๊ธฐ์กด ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋ฏ€๋กœ OCP๋ฅผ ๋งŒ์กฑ
  • ๊ธฐ์กด ์ฝ”๋“œ ๋ณ€๊ฒฝ์—†์ด ํ–‰์œ„๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” OCP๋ฅผ ์ค€์ˆ˜ํ•œ ๋””์ž์ธ ํŒจํ„ด

โž• GoF์˜ ๋””์ž์ธ ํŒจํ„ด์—์„œ์˜ ์ „๋žตํŒจํ„ด

  • ๋™์ผ ๊ณ„์—ด์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ตฐ์„ ์ •์˜ํ•˜๊ณ  (walk, run, fly, rocket)
  • ๊ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์บก์Šํ™”ํ•˜๋ฉฐ(MoveStrategy)
  • ์ด๋“ค์„ ์ƒํ˜ธ๊ตํ™˜์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค.

์ „๋žต์ด๋ž€?

์–ด๋–ค ๋ชฉ์ ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ผ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹.
๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™, ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋“ฑ (Random, Reverse, Nothing)

๊ตฌ์„ฑ

Context

  • ์ „๋žต ํŒจํ„ด์„ ์ด์šฉํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰
  • ํ•„์š”์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๊ตฌ์ฒด์ ์ธ ์ „๋žต์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋„๋ก ํ•จ (setter ๋˜๋Š” DI)

Strategy

  • ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ์™ธ๋ถ€์—์„œ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ช…์‹œ

ConcreateStrategy

  • ์ „๋žตํŒจํ„ด์—์„œ ๋ช…์‹œํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค

Example

๋ฐฐ๋ฏผ ๋กœ๋ด‡ ์ด๋™ ์ „๋žต ์˜ˆ์‹œ

  • Walk
  • Run
  • Fly
  • Rocket

์ดˆ๊ธฐ ๋ฐฐ๋‹ฌ ๋กœ๋ด‡

public class Robot {
    public void display() {
        System.out.println("๋ฐฐ๋‹ฌ ๋กœ๋ด‡");
    }
    
    public void move() {
        System.out.println("๊ฑธ์–ด์„œ ๋ฐฐ๋‹ฌํ•ฉ๋‹ˆ๋‹น.");
    }
}

๊ทธ๋Ÿฐ๋ฐ ์ด์ œ ๋‹ฌ๋ฆฌ๋Š” ๋กœ๋ด‡๋„ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค๋ฉด,

public class RunningRobot {
    public void display() {
        System.out.println("๋ฐฐ๋‹ฌ ๋กœ๋ด‡");
    }

    public void move() {
        System.out.println("๋›ฐ์–ด์„œ ๋ฐฐ๋‹ฌํ•ฉ๋‹ˆ๋‹น.");
    }
}

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

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ๋กœ๋ด‡์— ์˜จ๋„ ์กฐ์ ˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ, ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค” ๋ฌธ์ œ์ ?

  • ๋ฉ”์„œ๋“œ ์ˆ˜์ •์ด ์–ด๋ ต๋‹ค.
    • โ€œ๊ฑธ์–ด์„œ ๋ฐฐ๋‹ฌํ•˜๋Š” ๋กœ๋ด‡โ€์ด โ€œ๋น ๋ฅด๊ฒŒ ๊ฑธ์–ด์„œ ๋ฐฐ๋‹ฌํ•ฉ๋‹ˆ๋‹คโ€๋กœ ๋ณ€ํ•  ๊ฒฝ์šฐ ๋ชจ๋“  ํด๋ž˜์Šค๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ๋ฉ”์„œ๋“œ๋“ค์„ ์ˆ˜์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€๊ฐ€ ์–ด๋ ต๋‹ค.
    • ํ•œ๊ตญ์–ด, ์˜์–ด, ์ค‘๊ตญ์–ด๋ฅผ ๋งํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ๋‹ค๋ฉด ์ถ”์ƒ ํด๋ž˜์Šค์— ๋งํ•˜๊ธฐ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋  ๊ฒƒ์ด๊ณ , ์ด๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์— ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฐ๊ฐ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์ „๋žตํŒจํ„ด์ด๋‹ค!

  • ์ด๋™์ „๋žต : ๊ฑท๊ธฐ, ๋‹ฌ๋ฆฌ๊ธฐ, ๋‚ ๊ธฐ ๋“ฑ์˜ ๋กœ๋ด‡์˜ ํ–‰์œ„๋ฅผ ์ •์˜ํ•œ๋‹ค.
  • ์˜จ๋„ ์ „๋žต : cold, warm, hot๋“ฑ์„ ์ •์˜ํ•œ๋‹ค.

๋กœ๋ด‡์„ ์ƒ์„ฑํ•  ๋•Œ ๊ฐ๊ฐ์˜ ์ „๋žต์„ ์ฃผ์ž…ํ•ด์ฃผ์–ด ๋กœ๋ด‡์€ ์ „๋žต์˜ ํ–‰์œ„๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๋ฌธ์ œ์ ์ด ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐ๋ ๊นŒ?

  • ๋ฉ”์„œ๋“œ ์ˆ˜์ •์ด ์šฉ์ดํ•˜๋‹ค.
    • โ€œ๊ฑธ์–ด์„œ ๋ฐฐ๋‹ฌํ•˜๋Š” ๋กœ๋ด‡โ€์ด โ€œ๋น ๋ฅด๊ฒŒ ๊ฑธ์–ด์„œ ๋ฐฐ๋‹ฌํ•ฉ๋‹ˆ๋‹คโ€๋กœ ๋ณ€ํ•  ๊ฒฝ์šฐ walk ๋ถ€๋ถ„๋งŒ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€๊ฐ€ ์šฉ์ดํ•˜๋‹ค.
    • ํ•œ๊ตญ์–ด, ์˜์–ด, ์ค‘๊ตญ์–ด๋ฅผ ๋งํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ๋‹ค๋ฉด ์ด์— ๋”ฐ๋ฅธ ์ƒˆ๋กœ์šด ์ „๋žต์˜ ํ–‰์œ„๋ฅผ ์ •์˜ํ•ด์ฃผ๊ณ , ๋กœ๋ด‡์„ ์ƒ์„ฑํ•  ๋•Œ ์ „๋žต์„ ํ•จ๊ป˜ ์ฃผ์ž…ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ๋งŒ์•ฝ ์ด๋™๋ฐฉ์‹์ด ๋„์ค‘์— ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด?
    • setter๋“ฑ์„ ํ†ตํ•ด ๊ฐ์ฒด ์ƒ์„ฑ ํ›„ ์ „๋žต์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

JDK์—์„œ์˜ ์ „๋žตํŒจํ„ด

Comparator

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

Comparator๊ฐ€ ์ „๋žต์ด๊ณ  ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค customํ•˜๊ฒŒ ์ •์˜ํ•œ Comparator๊ตฌํ˜„์„ sort()๋ผ๋Š” ์ปจํ…์ŠคํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
๊ฐœ๋ฐœ์ž๋Š” ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋น„๊ต ์ „๋žต์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์—ฌ ๊ธฐ์กด ์ฝ”๋“œ์˜ ์ˆ˜์ •์—†์ด ํ™•์žฅ์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ