OCP (Open Closed Principle)

Open and Closed

"Open for extension But, Closed for modification"

ํ™•์žฅ์— ๋Œ€ํ•ด์„œ๋Š” ์—ด๋ ค์žˆ๊ณ  ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€์žˆ์–ด์•ผ ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ์˜ "Open for extendsion" ์ด๋ž€ ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ "Closed for modification" ์ด๋ž€ ์ด๋Ÿฌํ•œ ํ™•์žฅ์ด ์ผ์–ด๋‚  ๋•Œ ์ƒ์œ„ ๋ ˆ๋ฒจ์ด ์˜ํ–ฅ์„ ๋ฐ›์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์„ ์ž˜ ์ค€์ˆ˜ํ•œ๋‹ค๋ฉด, ์–ด๋–ค ๋ชจ๋“ˆ์˜ ํ–‰์œ„๋ฅผ ์†Œ์Šค์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ ์—†์ด ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

OCP Example

OCP๋ฅผ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”์ƒํ™”์™€ ์—ญ์ „(Inversion)์ด ํ•„์š”ํ•˜๋‹ค.

  • insert abstract interface between copy and device

  • cause the inverted dependencies

interface Reader {
    Integer getChar();
}

interface Writer {
    void putChar(Integer c);
}

public class Copy {

    public void copy(Reader reader, Writer writer) {
        Integer c;
        
        while ((c = reader.getChar() != null)) {
            writer.putChar(c);
        }
    }
}

class TestReader implements Reader {
    @Override
    public Integer getChar() {
        // do something...
    }
}

class TestWriter implements Writer {
    @Override
    public void putChar(Integer c) {
        // do something...
    }
}

Reader, Writer๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค๊ณ  Copy ํด๋ž˜์Šค์— ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚ ๊นŒ?

๋””๋ฐ”์ด์Šค(Reader, Writer)๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ํ•ด๋‹น ๋””์•„๋น„์Šค๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ, copy ๋กœ์ง์˜ ์ˆ˜์ •์€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

OCP๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ธ๊ฐ€?

OCP๋ฅผ ์ค€์ˆ˜ํ•˜๋ฉด ๋ณ€๊ฒฝ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?

  • ์ด๋ก ์ ์œผ๋กœ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ํ•˜์ง€๋งŒ, ์‹ค์šฉ์ ์ด์ง€ ์•Š๋‹ค.

2๊ฐ€์ง€ ๋ฌธ์ œ์ 

  • main partition

    • ๋ฉ”์ธ ํŒŒํŠธ์˜ ๊ฒฝ์šฐ if-else๊ฐ€ ์—†์„ ์ˆœ ์—†๋‹ค. ์Šคํ”„๋ง๊ณผ ๊ฐ™์ด DI ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ๋Œ€์‹ ํ•ด์ฃผ๋‹ˆ๊นŒ ๋ฐฐ์ œํ•˜๊ฒŒ ๋œ๋‹ค.

  • Crystal ball problem (๋งˆ๋ฒ•์˜ ์ˆ˜์ •๊ตฌ์Šฌ ๋ฌธ์ œ)

    • ๋‚˜๋„ ๋ชจ๋ฅด๋Š” ๊ฒƒ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‹ค ์ค€๋น„ํ•˜๋Š” ๋ฐฉ์‹์€ ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

    • ํ™•์žฅ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ธํ„ฐํŽ˜์ด์Šคํ™” ํ•œ๋‹ค๋ฉด ๊ต‰์žฅํžˆ ๋ณต์žกํ•ด์งˆ ๊ฒƒ์ด๋‹ค.

A Smelly Design

  public void printReport(ReportPrinter printer) {
    int total = 0;
    int mealExpenses = 0;

    printer.print("Expenses " + getDate() + "\n");

    for (Expense expense : expenses) {
      if (expense.type == BREAKFAST || expense.type == DINNER)
        mealExpenses += expense.amount;

      String name = "TILT";
      switch (expense.type) {
        case DINNER: name = "Dinner"; break;
        case BREAKFAST: name = "Breakfast"; break;
        case CAR_RENTAL: name = "Car Rental"; break;
      }
      printer.print(String.format("%s\t%s\t$%.02f\n",
        (  (expense.type == DINNER && expense.amount > 5000)
        || (expense.type == BREAKFAST && expense.amount > 1000)) ? "X" : " ",
        name, expense.amount / 100.0));

      total += expense.amount;
    }

    printer.print(String.format("\nMeal expenses $%.02f",mealExpenses / 100.0 ));
    printer.print(String.format("\nTotal $%.02f", total / 100.0));
  }

๋น„์šฉ(Expense) ๋ชฉ๋ก์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ฆฌํฌํŠธ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ฉ”์„œ๋“œ

  • ๊ฐ ๋น„์šฉ์˜ ์ข…๋ฅ˜์™€ ๊ธˆ์•ก์„ ์ถœ๋ ฅํ•˜๋ฉฐ, ์‹์‚ฌ ๋น„์šฉ(BREAKFAST, DINNER)์€ ๋ณ„๋„๋กœ ์ง‘๊ณ„

  • ๋ฆฌํฌํŠธ ํ•˜๋‹จ์— ์‹์‚ฌ ๋น„์šฉ ์ด์•ก๊ณผ ์ „์ฒด ๋น„์šฉ ์ด์•ก์„ ์ถœ๋ ฅ

์œ„ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์€ ๋ฌด์—‡์ผ๊นŒ?

  1. SRP ์œ„๋ฐ˜

  • ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™, ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ, ํฌ๋งทํŒ…๊ณผ ๊ฐ™์€ ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ์•„๋‹˜

  1. OCP ์œ„๋ฐ˜

  • ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ํ™•์žฅํ•˜๋ ค๋ฉด ์ˆ˜์ •์ด ํ•„์š”ํ•œ ์ƒํƒœ

  • ๋˜ํ•œ, ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ๋ฐ ํฌ๋งทํŒ…์„ ํ™•์žฅํ•˜๋ ค๋ฉด ์ˆ˜์ •์ด ํ•„์š”ํ•œ ์ƒํƒœ

Rigidity / Fragility / Immobility Problem

์œ„ ์ฝ”๋“œ์—์„œ์˜ ๋ฌธ์ œ์ ๋“ค์— ๋Œ€ํ•ด์„œ ๋ถ„์„ํ•ด๋ณด์ž.

๊ฒฝ์ง์„ฑ(Rigidity)

์‹œ์Šคํ…œ์—์„œ ํ•˜๋‚˜์˜ ๋ณ€๊ฒฝ์ด ๋ชจ๋“  ๋ณ€๊ฒฝ์„ ์œ ๋ฐœํ•  ๊ฒฝ์šฐ ๊ฒฝ์ง์„ฑ์ด ๋†’๋‹ค๊ณ  ํ•œ๋‹ค.

  • ์‹์‚ฌ ํƒ€์ž…(meal type)์— LUNCH, SNACK ๊ณผ ๊ฐ™์€ ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ๋Œ€์‘ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋Š”๊ฐ€?

Even though the design change is small, the impact is huge. So the system resist change. It's rigid.

์„ค๊ณ„ ๋ณ€๊ฒฝ์€ ์‚ฌ์†Œํ•ด ๋ณด์ด์ง€๋งŒ, ๊ทธ ์˜ํ–ฅ์€ ๋งค์šฐ ํฝ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‹œ์Šคํ…œ์€ ๋ณ€ํ™”์— ์ €ํ•ญํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ฒฝ์ง๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

์ทจ์•ฝ์„ฑ(Fragility)

์‹œ์Šคํ…œ์—์„œ ํ•˜๋‚˜์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด ์ „์ฒด์ ์œผ๋กœ ์ทจ์•ฝํ•œ ๋ถ€๋ถ„์ด ๋งŽ์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

  • switch๋ฌธ์ด๋‚˜ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ๋‚˜๋ˆŒ ๊ฒฝ์šฐ, ๋ณ€๊ฒฝ์„ ๊ฐ€ํ•  ๋•Œ ๋ˆ„๋ฝ๋˜๋Š” ๊ฒƒ์ด ์—†๋Š”์ง€, ์ž˜๋ชป ๋ณ€๊ฒฝํ•œ ๊ฒƒ์€ ์—†๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์ฒดํฌํ•˜์ง€?

์ฆ‰, Fan-out Problem์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ Fragilityํ•˜๋‹ค. ๋ชจ๋“  Design smell ์ค‘ Fragility๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ์ œ๊ฑฐํ•ด์•ผํ•  ๋Œ€์ƒ์ด๋‹ค.

๋ถ€๋™์„ฑ(Immobility)

์‹œ์Šคํ…œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋–จ์–ด์ง€๊ณ , ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์ด ์–ด๋ ค์šด ๊ฒƒ์„ ๋งํ•œ๋‹ค.

  • ๊ธฐ์—…์šฉ ์†”๋ฃจ์…˜์— ๋งž์ถฐ์ง„ ์‹œ์Šคํ…œ์„ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ์ž‘์€ ๋น„์ฆˆ๋‹ˆ์Šค ์˜์—ญ์œผ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์„๊นŒ?

The Lie

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

โ‡’ ๊ทธ๋ ‡๋‹ค๋ฉด, OCP๋ฅผ ์ค€์ˆ˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฏธ๋ž˜์— ์–ด๋–ค ์ผ, ์–ด๋–ค ํ™•์žฅ์ด ํ•„์š”ํ•œ์ง€ ๋ฏธ๋ฆฌ ๋‹ค ์•Œ์•„์•ผ ํ•œ๋‹ค๋Š” ๋ง์ธ๊ฐ€?

์šฐ๋ฆฌ๊ฐ€ ์•„๋ฌด๋ฆฌ ์ž˜ ์ค€๋น„ํ•˜๊ณ  ์˜ˆ์ธกํ•ด๋„, ๊ณ ๊ฐ์€ ์ค€๋น„ํ•˜์ง€ ๋ชปํ•œ ๊ฒƒ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€/๋ณ€๊ฒฝ์„ ์š”๊ตฌํ•œ๋‹ค.

โ‡’ ์ด ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋งˆ๋ฒ•์˜ ์ˆ˜์ • ๊ตฌ์Šฌ(Crystal ball)์ด ํ•„์š”ํ•œ๊ฑฐ ์•„๋‹Œ๊ฐ€?

์ด๊ฒƒ์ด OCP์— ๋Œ€ํ•œ ๋น„๋ฐ€์ด๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋ฏธ๋ž˜๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๋งŒ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Two Solutions

์šฐ๋ฆฌ๋Š” ๋ฏธ๋ž˜๋ฅผ ์˜ˆ์ธกํ•˜์ง€ ๋ชปํ•˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ OCP๋ฅผ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ์„๊นŒ?

Big Design Up Front(BDUF)

๊ณผ๋„ํ•œ ์„ค๊ณ„๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„์„ ์ž‘์„ฑํ•˜๊ธฐ ์ „, ์„ค๊ณ„๋ฅผ ๊ต‰์žฅํžˆ ๋งŽ์ด ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • ๊ณ ๊ฐ๊ณผ ๋ฌธ์ œ ์˜์—ญ์„ ๊ณ ์ฐฐํ•˜๋ฉฐ, ์š”๊ตฌ์‚ฌํ•ญ์„ ์˜ˆ์ธกํ•˜์—ฌ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๋งŒ๋“ ๋‹ค.

  • OCP๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋„๋ฉ”์ธ ๋ชจ๋ธ์— ์ถ”์ƒํ™”๋ฅผ ์ ์šฉํ•œ๋‹ค.

  • ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•œ ์ฒญ์‚ฌ์ง„์„ ์–ป์„ ๋•Œ ๊นŒ์ง€ ๋ฐ˜๋ณตํ•œ๋‹ค.

๋ฌธ์ œ

  • ํ•„์š”์น˜ ์•Š๋Š” ์ถ”์ƒํ™”๋กœ ๋„๋ฐฐ๋œ ๋งค์šฐ ํฌ๊ณ , ๋ฌด๊ฒ๊ณ  ๋ณต์žกํ•œ ์„ค๊ณ„๊ฐ€ ๋˜์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋‹ค.

  • ์ถ”์ƒํ™”๋Š” ์œ ์šฉํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๋งŒํผ ๋น„์šฉ๋„ ํฌ๋‹ค.

๋ง‰์ƒ ๊ณ ๊ฐ์€ ์šฐ๋ฆฌ๊ฐ€ ์ถ”์ƒํ™” ํ•ด๋…ผ ๊ฒƒ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์„ ์š”์ฒญํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ํšจ์œจ์ ์ธ ๋ฐฉ์‹์ด ์•„๋‹ˆ๋‹ค!

Agile Design - ์€์œ ๋ฒ•

์‹ค์šฉ์ ์ด๊ณ  ๋ฐ˜์‘์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐ€์žฅ ์ข‹์€ ์˜ˆ์‹œ๋ฒ•์€ ์€์œ ๋ฒ•(๋ฉ”ํƒ€ํฌ)์ด๋‹ค.

์€์œ ๋ฒ•

  • ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ๊ณ ๊ฐ์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋Œ์–ด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ์ผ์„ ํ•œ๋‹ค.

  • ๊ทธ๋ ‡๋‹ค๋ฉด ๊ณ ๊ฐ์€ ๊ทธ ๊ฒฐ๊ณผ๋ฌผ์— ๋Œ€ํ•ด ์š”๊ตฌ์‚ฌํ•ญ ๋ณ€๊ฒฝ์„ ์‹œ์ž‘ํ•œ๋‹ค.

  • ๋”ฐ๋ผ์„œ, ์–ด๋–ค ๋ณ€๊ฒฝ์ด ์š”๊ตฌ๋˜๋Š”์ง€ ์•Œ๊ฒŒ๋œ๋‹ค.

[์‹œ๋‚˜๋ฆฌ์˜ค]

- ๋ณ‘์‚ฌ๋“ค์ด ์ ๊ตฐ์˜ ์‚ฌ๊ฒฉ์— ํฌ์œ„๋๋‹ค.
- ์ดํƒ„์ด ๋‚œ๋ฐœํ•˜๊ณ  ์žˆ๋Š” ๊ฐ€์šด๋ฐ ์ฐธํ˜ธ์— ์ˆจ์–ด์žˆ๋‹ค.
- ์ ์„ ํ–ฅํ•ด ์ง‘์ค‘ ์‚ฌ๊ฒฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์ „ํˆฌ์—์„œ ์Šน๋ฆฌํ•œ๋‹ค.
- ๋ฌธ์ œ๋Š” ์–ด๋””์— ์ ์ด ์žˆ์„์ง€ ๋ชจ๋ฅธ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
- ์–ด๋–ค ๋ฐฉํ–ฅ์—์„œ ์ ๋“ค์ด ์ด์„ ์˜๋Š”์ง€ ๋ชจ๋ฅธ๋‹ค. 

BDUF ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•œ๋‹ค๋ฉด, ํฌ์œ„๋ง์ด ์ขํ˜€์ ธ ๋” ๋‚˜์œ ์ƒํ™ฉ์ด ๋˜์–ด๋ฒ„๋ฆฐ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ ์ƒ์‚ฌ๊ฐ€ XXX ์ผ๋ณ‘์—๊ฒŒ ์ผ์–ด๋‚˜๋ผ๊ณ  ๋ช…๋ นํ•œ๋‹ค.
=> ์ ๊ตฐ์ด ์‚ฌ๊ฒฉํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด์•Œ์ด ๋‚ ์•„์˜จ ๋ฐฉํ–ฅ์„ ์•Œ์•„๋‚ธ ๊ฒƒ์ด๋‹ค. (์ด๊ฒŒ ๋งž๋‚˜?)

์ด ๋‚ด์šฉ์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๋ณ€ํ™”์— ๋Œ€ํ•œ ๊ฐ€์žฅ ์ข‹์€ ์˜ˆ์ธก์€ ๋ณ€ํ™”๋ฅผ ๊ฒฝํ—˜ํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

๋ฌผ๋ก  ์šฐ๋ฆฌ๋Š” BDUF์™€ Agile ๋‘ ๊ทน๋‹จ ์‚ฌ์ด์— ์‚ด์•„๊ฐ„๋‹ค. BDUF๋Š” ํ”ผํ•ด์•ผ ํ•˜์ง€๋งŒ No DUF๋„ ํ”ผํ•ด์•ผ ํ•œ๋‹ค! ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด์„œ ์‚ฌ๊ณ ํ•˜๊ณ  Decoupled ๋ชจ๋ธ์„ ์‚ฌ์ „์— ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊ฐ€์น˜์žˆ๋Š” ์ผ์ด๋‹ค.

์ •๋ฆฌ ๋ฐ ํ•ต์‹ฌ

  • ์šฐ๋ฆฌ๋Š” ์™„๋ฒฝํ•œ ๋ฏธ๋ž˜๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋‹ค. ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด์„œ ์ถ”์ƒํ™”ํ•˜๋ฉฐ OCP๋ฅผ ์ค€์ˆ˜ํ•˜๋„๋ก ํ•˜์ž.

  • ๋„ˆ๋ฌด ๊นŠ์€ ์„ค๊ณ„๊ฐ€ ์•„๋‹Œ, ์ ์ ˆํ•œ ์‹œ์Šคํ…œ ๋ชจ๋ธ์— ๋Œ€ํ•œ ์‚ฌ์ „ ์„ค๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜์ž.

Last updated

Was this helpful?