
[Java] ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP) - 3. ๋์์ธ ํจํด์ด๋?
3) ๋์์ธ ํจํด์ด๋? ๐ง ๋ฐ๋ณต๋๋ ์ค๊ณ ๋ฌธ์ ์ ๋ํ ๊ฒ์ฆ๋ “์ด๋ฆ ์๋ ํด๋ฒ”์ ์นดํ๋ก๊ทธ์ฅ์ : ๊ณตํต ์ดํ ์ ๊ณต(์์ฌ์ํต↑), ์ฌ์ฌ์ฉ์ฑ↑, ์ ์ง๋ณด์์ฑ↑์ฃผ์: “ํจํด ์ ์ฉ์ ์ํด ๋ฌธ์ ๋ฅผ ์ต์ง๋ก
lxvxxu.tistory.com
๐ง 5.4 ์คํธ๋ํฐ์ง ํจํด์ด๋?
“์ ๋ต(Strategy)”์ ์ฝ๊ฒ ๋ฐ๊ฟ ์ ์๋๋ก ํด์ฃผ๋ ๋์์ธ ํจํด
- ์ ๋ต์ด๋ ์ด๋ค ๋ชฉ์ ์ ๋ฌ์ฑํ๊ธฐ ์ํ ํ๋ ๋ฐฉ์, ์๊ณ ๋ฆฌ์ฆ, ๊ท์น์ด๋ค.
- ์คํ ์ค์๋ ์ ๋ต(ํ๋ ๋ฐฉ์)์ ์ฝ๊ฒ ๊ต์ฒดํ ์ ์๋ค.
- ํนํ ๊ฒ์ ์บ๋ฆญํฐ์ฒ๋ผ ์ํฉ์ ๋ฐ๋ผ ๊ณต๊ฒฉ์ด๋ ํ๋์ ๋ฐ๊ฟ์ผ ํ ๋ ์ ์ฉํ๋ค.
โ ํน์ง
- ์๋ก ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๋ค์ด ์กด์ฌํ๊ณ , ์คํ ์์ ์ ์ ํฉํ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํด์ ์ฌ์ฉ
- ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๋จ์ํด์ง๊ณ ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋ค.
- ์๋ก์ด ์ ๋ต(์๊ณ ๋ฆฌ์ฆ) ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ ํ์ ์์.
๐ฌ ์์ ์ํฉ
- ์กฐ๋ฆฌ๋ฒ์ด ์ฌ๋ฌ ๊ฐ์ง์ผ ๋
- ํ์ผ์ ์์ถ ๋ฐฉ์์ด ๋ค๋ฅผ ๋
- ๊ฒฐ์ ๋ฐฉ์(ํ๊ธ, ์นด๋, ๋ฉค๋ฒ์ญ ๋ฑ)์ด ๋ค๋ฅผ ๋
- ์๋ฐ์ Comparator ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํ ์ ๋ ฌ ๋ฐฉ์ ์ ํ
๐ ์คํธ๋ํฐ์ง ํจํด ๊ตฌ์กฐ ์์ฝ
์์์ค๋ช
| ์ด๋ฆ | ์คํธ๋ํฐ์ง(Strategy) |
| ๋ฌธ์ | ์๊ณ ๋ฆฌ์ฆ์ ์ฌ๋ฌ ๋ฒ์ ์ด ์กด์ฌํด ์ค๋ณต๋๊ฑฐ๋ if๋ฌธ์ผ๋ก ์ ํํ๋ ์ฝ๋ ๋ฐ์ (OCP ์๋ฐ) |
| ํด๊ฒฐ | ๊ณตํต ๋ถ๋ถ์ ์ธํฐํ์ด์ค๋ก ์ถ์ํํ๊ณ , ์คํ ์์ ์ ์ ์ ํ ์ ๋ต ๊ฐ์ฒด๋ฅผ ์ฃผ์ |
| ๊ฒฐ๊ณผ | ์์ ์ด ํ์ํ ๋ ์๋ก์ด Strategy๋ง ์ถ๊ฐํ๋ฉด ๋จ. ๊ธฐ์กด ์ฝ๋๋ ๋ณ๊ฒฝ ์์ โ |
๐ ์ฌ๋ก 2 – ๋ผ๋ฉด ์กฐ๋ฆฌ ํ๋ก๊ทธ๋จ
๐ฅฃ ๋ค์ํ ์กฐ๋ฆฌ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ ์กฐ๋ฆฌ (cook)
- ๋ณถ์ ๋ผ๋ฉด (cookWithoutBroth)
- ์น์ฆ ๋ผ๋ฉด (cookWithCheese)
- ์์ด ๋ผ๋ฉด (cookWithVinegar)
- ์ฐ์ ๋ผ๋ฉด (cookWithMilk)
Version 1 – if๋ฌธ์ผ๋ก ์ฒ๋ฆฌ
class Ramen {
enum CookingMode { GENERAL, WITHOUT_BROTH, WITH_CHEESE, WITH_VINEGAR, WITH_MILK }
private CookingMode mode = CookingMode.GENERAL;
public void setCookMode(CookingMode mode) { this.mode = mode; }
public void cook() {
switch (mode) {
case GENERAL: cookWithGeneralRecipe(); break;
case WITHOUT_BROTH: cookWithoutBroth(); break;
case WITH_CHEESE: cookWithCheese(); break;
case WITH_VINEGAR: cookWithVinegar(); break;
case WITH_MILK: cookWithMilk(); break;
}
}
}
โ ๋ฌธ์ ์
- ์๋ก์ด ์กฐ๋ฆฌ๋ฒ์ ์ถ๊ฐํ ๋๋ง๋ค cook()์ ์์ ํด์ผ ํจ
- ์ฝ๋๊ฐ ์ ์ ๋ณต์กํด์ง → OCP ์๋ฐ
Version 2 – ์์์ผ๋ก ๋ถ๋ฆฌ
abstract class Ramen { public abstract void cook(); }
class GeneralRamen extends Ramen {
public void cook() { System.out.println("์ผ๋ฐ ์กฐ๋ฆฌ๋ฒ์ผ๋ก ๋์ด๊ธฐ"); }
}
class CheeseRamen extends Ramen {
public void cook() { System.out.println("์น์ฆ ๋ผ๋ฉด์ผ๋ก ๋์ด๊ธฐ"); }
}
โ ๋ฌธ์ ์
- ์๋ก์ด ์์ ์ข ๋ฅ๊ฐ ์ถ๊ฐ๋ ๋๋ง๋ค ํ์ ํด๋์ค๋ฅผ ๊ณ์ ๋ง๋ค์ด์ผ ํจ
- cook() ํจ์ ์ค๋ณต ๋ฐ์
โ Version 3 – ์คํธ๋ํฐ์ง ํจํด ์ ์ฉ
interface Recipe {
void cook();
}
class Ramen {
private Recipe recipe = new GeneralRamenRecipe();
public void setRecipe(Recipe recipe) { this.recipe = recipe; }
public void performCook() { recipe.cook(); }
}
class GeneralRamenRecipe implements Recipe {
public void cook() { System.out.println("์ผ๋ฐ ์กฐ๋ฆฌ๋ฒ์ผ๋ก ๋์ด๊ธฐ"); }
}
class CheeseRamenRecipe implements Recipe {
public void cook() { System.out.println("๋ผ๋ฉด์ ๋์ธ ํ ์น์ฆ ๋ฃ๊ธฐ"); }
}
public class Main {
public static void main(String[] args) {
Ramen ramen = new Ramen();
ramen.setRecipe(new CheeseRamenRecipe());
ramen.performCook();
}
}
โ ๊ฒฐ๊ณผ
- ์๋ก์ด ์กฐ๋ฆฌ๋ฒ ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋ ์์ ๋ถํ์
- ์คํ ์ค์๋ ์กฐ๋ฆฌ๋ฒ(์ ๋ต)์ ๊ต์ฒด ๊ฐ๋ฅ
- ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ํ์ฅ์ฑ์ด ๋ํญ ํฅ์
๐ ์ ๋ฆฌ
ํญ๋ชฉ๋ด์ฉ
| ํต์ฌ ๊ฐ๋ | ์๊ณ ๋ฆฌ์ฆ(์ ๋ต)์ ์ธํฐํ์ด์ค๋ก ์บก์ํํ๊ณ ์คํ ์ ๊ต์ฒด |
| ์ฃผ์ ์ด์ | OCP ์ค์, ์ฝ๋ ์ค๋ณต ์ ๊ฑฐ, ์ ์ฐํ ๊ตฌ์กฐ |
| ๋ํ ์์ | ๋ก๋ด ๊ณต๊ฒฉ/์ด๋ ๋ฐฉ์, ๋ผ๋ฉด ์กฐ๋ฆฌ๋ฒ, ์ ๋ ฌ ๋ฐฉ์ ์ ํ |
| ํค์๋ | ์บก์ํ, ์ ์ฐ์ฑ, ์ ๋ต ๊ต์ฒด, ์ธํฐํ์ด์ค |