#1 ํ๋ก๊ทธ๋จ์ ์ด๋ช ๊ณผ ์ค๊ณ
์ธ๊ฐ์ ์ด๋ช ์ ๋ช ํํ๋ค. ํน์ด์ ์ด ์ค์ง ์๋๋ค๋ ๊ฐ์ ํ์, ์ธ๊ฐ์ ์ธ์ ๊ฐ ๋ฐ๋์ ์ฃฝ๋๋ค. ํ๋ก๊ทธ๋จ์ ์ด๋ช ๋ ๋ช ํํ๋ค. ํ ๋ฒ ๊ฐ๋ฐ๋ ํ๋ก๊ทธ๋จ์, ๋ฏธ๋์ ๋ฐ๋์ ๋ณ๊ฒฝ(์ ์ง๋ณด์)๋๋ค.
'์ด๋ช '์ ๊ณ ๋ คํ๋ฉด ํ๋ก๊ทธ๋๋ฐ์์ '์ข์ ์ค๊ณ'๊ฐ ๋ฌด์์ธ์ง ๋ ์ฌ๋ฆด ์ ์๋ค. ๋ฐ๋ก, ๋ณ๊ฒฝ์ ๊ฐํ ์ค๊ณ(๊ตฌ์กฐ)๋ค. ์๋์ ์๋ ๋ง์ ๋ค ๊ฐ์ ๋ง์ด๋ค.
๋ณ๊ฒฝ์ ๊ฐํ ์ค๊ณ(๊ตฌ์กฐ)
= ์๋ก์ด ์๊ตฌ์ฌํญ์ด๋ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ๋, ๋ฐ๊ฟ์ผ ํ๋ ์ฝ๋์ ๋ฒ์๊ฐ ์ข์ ๊ตฌ์กฐ
= ๋ณ๊ฒฝ์ ์ ์ฐํ๊ฒ ๋์ฒ๊ฐ ๊ฐ๋ฅํ ๊ตฌ์กฐ
= ํ์ฅ์ฑ์ด ๋์ ๊ตฌ์กฐ
#2 SOLID ์์น
#2-1 WhatใWhy
#1์์ ๋งํ '๋ณ๊ฒฝ์ ๊ฐํ' ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๊ณ ์๋ 5๊ฐ์ง ํจํด(์์น)์ด๋ค. S,O, L, I, D์ ๊ฐ ์ํ๋ฒณ์ด ํจํด ํ๋์ ๋์ํ๋ค.
#2-2 ์ด๋ชจ์ ๋ชจ
- ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋จ๊ณจ ๋ฉด์ ์ง๋ฌธ ์ค ํ๋๋ค.
- ํ๋์ ๋ง์ ๋์์ธ ํจํด์ด SOLID ์ค๊ณ ์์น์ ๋ฐ๋ผ์ ๋ง๋ค์ด์ก๋ค. (SOLID๊ฐ ๊ทผ๊ฐ).
- ๋์ ๋๋ ์ฒ ์๋ก ๋ง๋ค๊ธฐ ์ํด S → O → L → I → D ์์ผ๋ก ๋ฐฐ์ด๋์์ ๋ฟ, 5์์น ๊ฐ ์ฐ์ ์์๋ ์๋ค.
- 5๊ฐ์ง ์์น๋ค์ ์๋ก ์์ ํ ๋ ๋ฆฝ๋ ๊ฐ๋ณ์ ์ธ ๊ฐ๋ ์ด ์๋๋ผ ๊ฐ๋ ์ ์ผ๋ก ์ฐ๊ด๋์ด ์๋ค. ์์น๋ผ๋ฆฌ ์๋ก์๋ก ์ด์ฉํ๊ธฐ๋ ํ๊ณ ์ผ๋ถ ๊ฒฝ์ฐ์์ ํฌํจ ๊ด๊ณ๋ฅผ ์ด๋ฃฐ ์ ์๋ค.
- ์ฝ๋์ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ์ต์ง๋ก ์งํค์ง ์์๋ ๋๋ค. ๋ S, O, L, I, D ์ ๋ถ๊ฐ ์๋๋ผ ์ผ๋ถ๋ง ์ง์ผ๋ ๋๋ค. (ํ์๋ณด๋จ ๊ธฐ๋ฅ!).
#3 [S] ๋จ์ผ ์ฑ ์ ์์น
Single Responsibility Principle, SRP
#3-1 What
ํ๋์ ํด๋์ค๋ ํ๋์ '์ฑ ์'๋ง์ ์ง๋ ์ผ ํ๋ค.
* ์ฑ ์(Responsibility): ์กด์ฌ ์์ (์ญํ , ๊ธฐ๋ฅ ๋ฑ)
๋ง์ฝ ํ๋์ ํด๋์ค์ ๊ธฐ๋ฅ(์ฑ ์)์ด ์ฌ๋ฌ ๊ฐ ์๋ค๋ฉด, ๊ธฐ๋ฅ ๋ณ๊ฒฝ(์์ )์ด ์ผ์ด๋ฌ์ ๋ ์์ ํด์ผ ํ ์ฝ๋๊ฐ ๋ง์์ง๋ค. ๋ด๊ฐ ์ค๊ณํ ํด๋์ค๊ฐ ๋ง์ฝ ๋ฏธ๋์ ๋ณ๊ฒฝ๋๋ค๋ฉด, ๊ทธ ์ด์ ๋ ํ ๊ฐ์ง ์ข ๋ฅ์ '์ฑ ์(Responsibility)' ๋๋ฌธ์ด์ด์ผ ํ๋ค.
#3-2 'Ripple Effect'๋
UI ๋์์ธ์์๋, (๋ฒํผ ํด๋ฆญ ์ ๋ฑ ๋์) ์๊ฐ์ ๋ฌผ๊ฒฐ(Ripple) ํจ๊ณผ๋ฅผ ์๋ฏธํ๋ค. ํ๋ก๊ทธ๋๋ฐ์์๋ ๋ค๋ฅธ ํ๋๋ ์ฝ๋ ๋ณ๊ฒฝ ์ ์๊ธฐ์น ์๊ฒ ๋ฐ์ํ๋ ์ฝ๋์ ์ฐ์์ ์ธ ์ํฅ(ํ๊ธ ํจ๊ณผ)์ ์๋ฏธํ๋ค. ์ฌ๊ธฐ์๋ Ripple Effect๋ฅผ ํ์์ ์๋ฏธ๋ก ์ฌ์ฉํ๋ค.
#3-3 ์์ใ๊ธฐ๋ ํจ๊ณผ
SRP๋ฅผ ์งํค์ง ์์ ์์
๊ธฐ๋ฅ(์ฑ ์)์ ์ฌ๋ฌ ๊ฐ ๊ฐ์ง ํด๋์ค A๊ฐ ์์ ๋,
A์ ํน์ ๊ธฐ๋ฅ์ ๋ณ๊ฒฝํ๋ฉด
→ ์ฐ๊ด๋ ํด๋์ค B ์์
→ ์ฐ๊ด๋ ํด๋์ค C ์์
→ ์ฐ๊ด๋ ํด๋์ค D ์์
Ripple Effect๊ฐ ๋ฐ์ํ๋ ์์๋ค. ์์ ์์์์ ๋ ๋์๊ฐ ๋ง์ฝ D์ ์์ ์ฌํญ์ด A์๊ฒ Ripple Effect๋ฅผ ์ผ์ผํจ๋ค๋ฉด, Ripple Effect๊ฐ A์์ ์์ํด์ A๋ก ๋์์ค๋ ์ํ ํํ๊ฐ ๋๊ณ ๋ง๋ค. ํผ๋ ๊ทธ ์์ฒด๋ค. ๋ง์ฝ SRP๋ฅผ ์ค์ํ๋ค๋ฉด ์ฝ๋ ๋ณ๊ฒฝ์ด ํ๋์ ํด๋์ค ๋ด๋ถ๋ก ํ์ ๋์์ ๊ฒ์ด๋ค (= Ripple Effect๊ฐ ๋ฐ์ํ์ง ์์์ ๊ฒ์ด๋ค).
๊ธฐ๋ ํจ๊ณผ
SRP ํจํด์ ์ค์ํ์ฌ, Ripple Effect๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
#4 [O] ๊ฐ๋ฐฉ ํ์ ์์น
Open Closed Principle, OCP
#4-1 What
(์ธํฐํ์ด์ค๋) ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค๋ฅผ ๋ง๋ค ๋, ๊ธฐ์กด ์ฝ๋(๋ถ๋ชจ ํด๋์ค)๋ฅผ ์์ ํ ํ์๊ฐ ์์ด์ผ ํ๋ค.
์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด์, ๋ถ๋ชจ ํด๋์ค์๋ '์ต์ํ์ ์ถ์ํ(#4-2) ์ฝ๋'๋ง์ ๋จ๊ธฐ๊ณ ๋๋จธ์ง๋ ์ ๊ฑฐํด์ผ ํ๋ค.
#4-2 '์ถ์'์ด๋
- ํ์ค๊ตญ์ด๋์ฌ์ : ์ฌ๋ฌ ๊ฐ์ง ์ฌ๋ฌผ์ด๋ ๊ฐ๋ ์์ ๊ณตํต๋๋ ํน์ฑ์ด๋ ์์ฑ ๋ฐ์๋ฅผ ์ถ์ถํ์ฌ ํ์ ํ๋ ์์ฉ (๋งํฌ)
- ๊ทธ๋๋ ๋ถ์น(Grady Booch): ๋ค๋ฅธ ๋ชจ๋ ์ข ๋ฅ์ ๊ฐ์ฒด๋ก๋ถํฐ ์๋ณ๋ ์ ์๋ ๊ฐ์ฒด์ ๋ณธ์ง์ ์ธ ํน์ง
์ฌ๊ธฐ์์ '์ถ์'์ ๋ฌ์ฌํ ๋ ์ผ๋ฐ์ ์ผ๋ก ํต์ฉ๋๋ ์ค๋ช ์, #4-4์์ '์ถ์'์ ๋ณธ์ง์ ์ธ ์ค๋ช ์ ๋ค๋ฃฌ๋ค. ์ถ์์ '๊ณตํต๋ ๊ฒ'์ด๋ผ๊ณ ์ค๋ช ๋๋ ๊ฒ ์ผ๋ฐ์ ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฆผ 'ํ์ ๋๋ฌด'์ ์๋ ๋ฌผ์ฒด๋ฅผ '๋๋ฌด'๋ผ๊ณ ์ธ์ํ๋ ์ด์ ๋, ๊ทธ ๊ทธ๋ฆผ์์ ํ์ค์ ๋๋ฌด๋ค์ด ๊ณตํต์ผ๋ก ์ง๋๋ ํน์ฑ์ ์๋ณํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
#4-3 ์์ใ๊ธฐ๋ ํจ๊ณผ
OCP๋ฅผ ์งํค์ง ์์ ์์
open class Animal {
// ์๋ก์ด ๋๋ฌผ(์: Fox)์ ์ถ๊ฐํ๋ ค๋ฉด ์ด when ๋ฌธ์ ๋ฐ๋์ ์์ ํด์ผ ํจ → OCP ์๋ฐ
fun speak(animal: Animal): String {
return when (animal) {
is Dog -> "์"
is Cat -> "๋ฅ"
else -> "..."
}
}
}
class Dog : Animal()
class Cat : Animal()
์์ ์ฝ๋๋ฅผ #4-2์ ์๋ '์ถ์' ๊ฐ๋ ์ผ๋ก ์ค๋ช ํ์๋ฉด, ๋๋ฌผ๋ค์ ๊ณตํต์ผ๋ก ์๋ฆฌ๋ฅผ ๋ธ๋ค(Speak)๋ ํน์ฑ์ ์ฝ๋(Animal.speak())๋ก ์ฎ๊ธด ๊ฒ์ด๋ค. ํ์ง๋ง ๊ทธ ์ถ์์ ์ต์ํํ์ง ์์๋ค. ๋ค์ ๋งํด, speak() ๋ถ๋ถ์ ์ฝ๋๊ฐ ๊ณผ๋ํ๊ฒ ๋ง๋ค. ๊ทธ๋์ Animal์ด๋ผ๋ ๋ถ๋ชจ๋ฅผ ๋ฐ๋ฅด๋ Cat, Dog ํด๋์ค์ speak() ๋ฉ์๋ ๊ตฌํ์ ์ํด์ , '๊ธฐ์กด ์ฝ๋(์ฌ๊ธฐ์ Animal์ ์ฝ๋)๋ฅผ ๊ณ ์ณ์ผ ํ๋' ์ํฉ์ด ๋์ด๋ฒ๋ ธ๋ค.
OCP๋ฅผ ์งํจ ์์
// ์์ ์ฝ๋๋ฅผ ์์ ํด OCP ์ค์ํ๊ฒ ๋ง๋ฆ
open class Animal {
open fun speak(): String = "..."
}
class Dog : Animal() {
override fun speak() = "์"
}
class Cat : Animal() {
override fun speak() = "๋ฅ"
}
---
// ์ด๋ ๊ฒ Animal์ interface๋ก ๋๋ ๋ฐฉ์์ ์์ ๋ ์ข๋ค
interface Animal {
fun speak(): String
}
class Dog : Animal {
override fun speak() = "์"
}
class Cat : Animal {
override fun speak() = "๋ฅ"
}
๋ฐ๋ฉด speak()์ '์ต์ํ๋ ์ถ์ ์ฝ๋'๋ก ๋ฐ๊พธ๋ฉด ์ด๋จ๊น? ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ๋ Cat, Dog ๋ฑ์ ์ ์ธ ๊ฐ๋ฅํ ๋งํผ speak()์ ๊ฒฝ๋ํํ๋ค. ๋ฐ๋ผ์ ์์ ์ฝ๋๋ OCP๋ฅผ ์งํจ ์ฝ๋๊ฐ ๋๋ค.
๊ธฐ๋ ํจ๊ณผ
OCP ํจํด์ ์ค์ํ์ฌ, ๊ธฐ์กด ์ฝ๋ ์์ ์์ด ์์ฝ๊ฒ ๊ธฐ๋ฅ ํ์ฅ์ด ๊ฐ๋ฅํด์ง๋ค.
#4-4 ์ง์ง '์ถ์'
๋ณธ์ง(What) ์ฐพ๊ธฐ
์ถ์ = ๊ตฌ์กฐ = ์ ์ฑ
(์ถ์ํ = ๊ตฌ์กฐํ = ์ ์ฑ ํ)
#4-2์์ '์ถ์'์ ๋ฌ์ฌํ ๋ ํต์ฉ๋๋ ์ค๋ช ์ ๋ค๋ค์ง๋ง, ์ฌ๊ธฐ์์ '์ถ์'์ ๋ณธ์ง์ ์ธ ์ค๋ช ์ ๋ค๋ฃฌ๋ค. ์ฌ์ค ์ถ์์ด๋, ๊ทธ๋ฅ '๊ตฌ์กฐ'์ ๋ถ๊ณผํ๋ค. #4-2์์ ์ธ๊ธํ๋ '๊ณตํต'์ด๋ผ๋ ํค์๋๋ ์ฌ๊ธฐ์ ์๋ค. ๋ ๊ธ์ '๊ตฌ'์ '์กฐ'๊ฐ ์ค๋ช ์ ์ ๋ถ๋ค. ๋๋ ์ถ์์ด ๊ทธ์ '๊ตฌ์กฐ'์ ํํ์ ํํ์ ๋ถ๊ณผํ๋ค๊ณ ๊ฐํ ์ฃผ์ฅํด ๋ณธ๋ค. ์๋๋ ์ฌ๋์ '์ถ์ํํ' ๊ทธ๋ฆผ 2๊ฐ์ ๋ํ ๋น๊ต๋ค.

์ด์งธ์ ์กธ๋ผ๋งจ์ ํ๊ณผ ๋ค๋ฆฌ๊ฐ ์๋๋ฐ, ํ์ฅ์ค ํ์งํ ์ฌ๋์๊ฒ ์๋๊ฐ? ์ผ๋ฐ์ ์ธ ์ฌ๋์ ๋๊ตฌ๋ ๊ณตํต์ผ๋ก ๊ฐ์ง๋ ๊ฒ ์๋๊ฐ? ์ด ๋ฐ๋ก๋ฅผ ํตํด ์ถ์์ด๋ (๋์์ด๋๊ฐ ์์๋ก ์ ํ) '๊ตฌ์กฐ'๋ฅผ ์ด๋ ต๊ฒ ํํํ ๋จ์ด์ผ ๋ฟ์ด์ง, '๊ณตํต'์ ๋ค๋จน์ด๋ฉฐ ์ค๋ช ํ ํ์๊ฐ ์๋ ๊ฐ๋ ์์ ์ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ ๊ทธ๋ฐ ์ค๋ช ์ด ๋์ค๊ฒ ๋์์๊น? ๊ทธ๊ฒ์ ๋ฐ๋ก What๊ณผ How๋ฅผ ํผ๋ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ถ์์ ๋ฌด์(What, ๋ณธ์ง)์ธ๊ฐ? → ๊ตฌ์กฐ
์ถ์์ ์ด๋ป๊ฒ(How, ๋ฐฉ๋ฒ) ํด์ผ ์ ๋ฝ์๋ด๋๊ฐ? → ๊ณตํต์ ์ ์ฐพ์์
์ด๋ ๋ฏ, What์ ๋ํด ์ค๋ช ํด์ผ ํ๋๋ฐ How์ ๋ํ ์ค๋ช ์ ํด๋ฒ๋ฆฐ ๊ฒ์ด๋ค. ๋ฌผ๋ก ์ผ๋ฐ์ ์ผ๋ก ํต์ฉ๋๋ ์ค๋ช ์์, ์ถ์์ '๊ตฌ์กฐ'๋ผ๊ณ ํ ์ ์๋ ๋ ธ๋ฆ์ธ ๊ฒ๋ ์ธ์ ํ๋ค. ๋๋ฌด ์งง์์ ๋ฌด์ฑ์ํ๊ฒ ๋ณด์ผ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์๋์ ๊ฐ์ด ๋ฐ๋ฌธํ ์๋ ์๋ค.
์กธ๋ผ๋งจ๊ณผ ํ์ฅ์ค ํ์งํ ์ฌ๋ ๋ชจ๋ '์ฌ๋'์ด๋ผ๋ฉด ๊ณตํต์ผ๋ก ๊ฐ์ง๊ณ ์๋ '๋จธ๋ฆฌ'๋ฅผ ๋๊ทธ๋ผ๋ฏธ๋ก ํํํ๋๋ฐ, ๋ฐ๋ก๋์๊ณ ์ ์ํ ์์๋ง์ ๋ ๊ฒฐ๊ตญ ๊ณตํต์ ๊ฐ๋ ์ด ๋ค์ด๊ฐ ์๋ ๊ฒ์ด ์๋๊ฐ?
๊ทธ๋ ๋ค๋ฉด ์ฌ๋ ๋จธ๋ฆฌ๋ฅผ ๋ค๋ชจ๋ก ํํํ๋ ์ถ์์ ์ด๋ค๊ฐ? ์๋๋ฉด ์์ ๋จธ๋ฆฌ๋ถํฐ ๋ฐ๋๊น์ง๋ฅผ ํต์งธ๋ก ํ๋์ ์ (.)์ผ๋ก ํ์ํ ์๋ ์๊ณ , ํน์ ํ ์ซ์๋ก ํ์ํ ์๋ ์๋ค. ์ด๋ค ํํ๋ ๊ทธ๊ฑด ๋์์ด๋์ ๋ง์์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ถ์์ '์' ํ๊ธฐ ์ํด์ '๊ณตํต'์ ์ ์ ๋ฝ์๋ด์ผ ํ๋ ๊ฑด ๋ง์ง๋ง, ์์ ๋งํ๋ฏ ๊ทธ๊ฑด ์ถ์์ How์ง What์ด ์๋๋ค.
์ข์ ๋ฐฉ๋ฒ(How)
์ง๊ธ๊น์ง ์ผ๋ฐ์ ์ผ๋ก ํต์ฉ๋๋ ์ถ์์ ์ ์์์ ๋ณธ์ง(What)๊ณผ ๋ฐฉ๋ฒ(How)์ ๋ถ๋ฆฌํ๋ค๋ฉด, ์ง๊ธ๋ถํด ๋ถ๋ฆฌ๋ ๋ถ๋ถ ์ค How๋ฅผ ์ง์ค์ ์ผ๋ก ๊ณต๋ตํด๋ณธ๋ค. ๋ค์ ๋งํด ์ด๋ป๊ฒ ํด์ผ ์ถ์ํ๋ฅผ ์ํ ์ง์ ๋ํ ์ค๋ช ์ด๋ค. ์ข์ ์ถ์์ 2๊ฐ์ง ์์์ ์ค๋ค๋ฆฌ๊ธฐ์์ ๋์ค๋๋ฐ, ๊ทธ ์์๋ ์๋์ ๊ฐ๋ค.
1. ์ ์ฐํจ (๊ณตํต์ ์ ์ข๊ฒ ์ก์ = "xxx ์ค ์ผ๋ถ๋ง์ด ๊ทธ๋")
2. ๊ฐ๋ ์ฑ (๊ณตํต์ ์ ๋๊ฒ ์ก์ = "xxx๋ ๋ค ๋๊ฐ์")
์ด ์์์ ํจ๊ป #4-3์ ์์๋ฅผ ๋ค์ ๋ณด์. Animal์ ์๋ฆฌ๋ฅผ ๋ด๋ ๊ณตํต์ ์ด ์๋ค๊ณ ํ์ง๋ง, ์ ๋ง๋ก ๊ทธ๋ด๊น?
class Shell : Animal() { // ์กฐ๊ฐ
override fun speak() = "???" // ๋
ผ๋ฆฌ์ ์๋ฌ
}
์ด ์ฝ๋์์๋ ๋ ผ๋ฆฌ์ ์ค๋ฅ๊ฐ ๋๋ค. ์กฐ๊ฐ๋ ๋๋ฌผ์ด์ง๋ง ์๋ฆฌ๋ฅผ ๋ผ ์ ์๋ค. ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์, ๋ชจ๋ ๋๋ฌผ์ด ๋งํ ์ ์๋ค๋ ์์ผ๋ก ๊ณตํต์ ์ ๋๋ฌด ๋๊ฒ ์ก์๊ธฐ ๋๋ฌธ์ด๋ค. ๋น์ทํ๊ฒ ๋ชจ๋ ์ฐจ(Car)์๋ ๋ฐํด๊ฐ ์๋ค๊ณ ๊ณตํต์ ์ ์ก์ผ๋ฉด, ํฑํฌ์ ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ์ง ๋ชปํ๊ฒ ๋๋ค. ๋ชจ๋ ์ฌ๋์๊ฒ ๋จธ๋ฆฌ์นด๋ฝ์ด ์๋ค๊ณ ๊ณตํต์ ์ ์ก์๋ฒ๋ฆฌ๋ฉด, ํ๋ชจ ์ธ๊ตฌ๋ฅผ ์ปค๋ฒํ์ง ๋ชปํ๊ฒ ๋๋ค.
open class Animal
open class SpeakableAnimal : Animal() {
open fun speak(): String = "..."
}
class Dog : SpeakableAnimal() {
override fun speak() = "์"
}
class Cat : SpeakableAnimal() {
override fun speak() = "๋ฅ"
}
class Shell : Animal() // ์กฐ๊ฐ
๋ชจ๋ Animal์ด speak()์ ํ ์ ์๋ค๊ณ ํ๋ ๋์ , ๋ ์ข์ ๋ฒ์์ธ SpeakableAnimal๋ง์ด speak()์ ํ ์ ์๊ฒ ํ๋ค. ์ฆ, ๊ณตํต์ ์ ๋ฒ์๋ฅผ ์ค์๋ค. ๊ณตํต์ ์ ์ค์ด๋ฉด ์ ์ฐ์ฑ์ด ์๊ธฐ์ง๋ง, ๊ณตํต์ ์ ์ค์ธ ๋งํผ ์๊ธด ์ฐจ์ด์ ์ ๊ดํด ๊ธฐ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฝ๋์์ด ๋์ด๋์ ๊ฐ๋ ์ฑ์ ๋จ์ด์ง๋ค.
๋ชจ๋ ๋๋ฌผ์ ์ธ์์๋ฆฌ๋ฅผ ๋ธ๋ค → ์ผ๋ถ ๋๋ฌผ๋ง์ด ์ธ์์๋ฆฌ๋ฅผ ๋ธ๋ค
์ ๊ฐ์ด ๊ณตํต์ ์ ๋ฒ์๋ฅผ ์ขํ๋๋, ์ ์ฐํจ์ด ์ฆ๋๋๊ณ ์ฝ๋์์ด ๋์ด๋์ ๊ฐ๋ ์ฑ์ ํ๋ฝํ๋ค. ๋ง์ฝ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ๊ณตํต์ ์ ๋ฒ์๋ฅผ ๋ํ๋ค๋ฉด, ์ ์ฐํจ์ด ๊ฐ์ํ์ ๊ฒ์ด๊ณ ์ฝ๋์์ด ์ค์ด๋ค์ด ๊ฐ๋ ์ฑ์ ํฅ์๋์์ ๊ฒ์ด๋ค. ์ด๋ ๋ฐฉํฅ์ด๊ฑด ๊ทน๋จ์ผ๋ก ๊ฐ๋ฉด ์ ์ข๋ค๋ ๊ฑธ ์ง๊ฐ์ ์ผ๋ก ๋๋ ์ ์๋ค. ๋ ๊ทน๋จ ์ฌ์ด์์ ๊ท ํ์ ์ก๋ ๋ฐ์๋, ์๋ จ๋ ํ๋ก๊ทธ๋๋จธ์ ๋ ธ๋ จํ ๊ฐ๊ฐ์ด ๋ถ๋ช ํ ์๊ตฌ๋ ๊ฒ์ด๋ค.
#4-5 TMI
#4-4์์ ๋งํ ์กธ๋ผ๋งจ์ ๋ค์ ๋ณด์. ์ (ํ์ฅ์ค ํ์งํ ์ฌ๋๊ณผ ๋ฌ๋ฆฌ) ์กธ๋ผ๋งจ์ ์ฌ์ง๊ฐ ๋ฉ์ฉกํ ๊น? ์กธ๋ผ๋งจ์ ์ฃผ๋ก ๊ต๊ณผ์ ๊ตฌ์ ๋์์ ๋์ค๋ ๋ฑ์ฅ์ธ๋ฌผ์ด๊ณ , ๋์์ด๋๋ ์ญ์คํ๊ตฌ ์์ ์๊ฐ์ด ์ง๋ฃจํด์ ๋์ ์ค์ธ ์ด๋ฑํ์์ด๋ค. ๊ทธ๋ฐ ์ด๋ฑํ์๋ค์ 99%๋ ์กธ๋ผ๋งจ๋ค๋ผ๋ฆฌ ์ธ์ฐ๋ ๋ชจ์ต์ ๊ทธ๋ฆด ํ ๋ฐ, ์ธ์ ๋ฌ์ฌ๋ฅผ ์ํด ํ๊ณผ ๋ค๋ฆฌ์ ์กด์ฌ๋ ํ์์ ์ด๋ค.
์กธ๋ผ๋งจ์๊ฒ ๊ฐ์ ๋ก ์ ์ฐํจ์ ๋ถ์ฌํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ์กธ๋ผ๋งจ์ ๋ชธํต์ ์ผ์ง์ ์ด๋ค. ์ฌ๊ธฐ์ ์ผ์ง์ ๋์ ํ์ฅ์ค ํ์งํ ์ฌ๋์ฒ๋ผ '๊ฑฐ๋ํ ๋ชธํต'์ ๊ทธ๋ ค ๋ฃ๊ฒ ๊ฐ์ ํด ๋ณด๋ ๊ฒ์ด๋ค. ์ด๋ฑํ์์ ๋ฐ์์ ์๋ง ์ด๋ด ํ ๋ค: "๊ทธ๋ฅ ์กธ๋ผ๋งจ๋ผ๋ฆฌ ์ธ์ฐ๋ ๊ฒ๋ง ๊ทธ๋ฆฌ๊ณ ์ถ์๋ฐ, ๊ท์ฐฎ๊ฒ ๋ชธํต๋ ๊ทธ๋ ค ๋ฃ์ด์ผ ํด? ์ฐจ๋ผ๋ฆฌ ์์ ์ ๋ฃ๊ณ ๋ง์ง!". ์กธ๋ผ๋งจ์ ๋ ๊ฑด๋ค์ผ ํ์ ์๋ ์ต์ํ์ ์ถ์์ด๋๊น.
ํํธ, ํ์ฅ์ค ํ์งํ ์ฌ๋์ ์ธ์ธ ์ผ์ด ์๋ค. ๊ฐํน ํ์ฅ์ค ํ์งํ์์ ํ๊ณผ ๋ค๋ฆฌ๋ฅผ ๋ฌ์ฌํ๋ ๋๋ ์์ผ๋, ๊ทธ๋ฐ ์ํฉ์๋ ํ๊ณผ ๋ค๋ฆฌ๋ ์ด์ฐจํผ ์๋ฌด๋ฐ ๋์๋ ์๋ฏธ๋ ์๋ค. ๋ ํ์ฅ์ค ํ์งํ ์ฌ๋๋ค์ ๋ชธํต์ด ๋ฐ๋์ ์ผ์๊ฐ ์๋๋ค. ๋ง์ฝ ์ผ์ง์ ์ด๋ผ๋ฉด ๋จ์ ํ์ฅ์ค์ธ์ง ์ฌ์ ํ์ฅ์ค์ธ์ง์ ํ์๋ฅผ ์ํ ์์ ์ฑ์ ๋ฃ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ฅ์ค ํ์งํ ๋ํ ์ธ์์ด ํ๋ฅด๋ฉฐ ์ ํํ๋ ์ต์ํ์ ์ถ์์ด๋ค.
#5 [L] ๋ฆฌ์ค์ฝํ ์นํ ์์น
Liskov Substitution Principle, LSP
#5-1 What
ํ์ ํ์ ์ ์์ ํ์ ์ผ๋ก ๋์ฒดํ (์นํ) ์ ์์ด์ผ ํ๋ค.
์์๋ฐ์ ์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค์ฒ๋ผ ๋ค๋ค๋ ๋ ผ๋ฆฌ์ ์ผ๋ก(='๊ธฐ๋ฅ'์ ์ผ๋ก) ๋๊ฐ์ด ๋์ํด์ผ ํ๋ค. ๊ตฌํ์ฒด(์์)๋ฅผ ๋ฐ๊ฟ๋ ์ฝ๋์ ์๋ฏธ(๋ฉ์๋๋ณ๋ก ์ง๋๋ ๋์์ ์ถ์์ ์ธ ๊ธฐ๋)๊ฐ ๊นจ์ง์ง ์์์ผ ํ๋ค๋ ๋ง์ด๋ค.
#5-2 '์บ์คํ '์ด๋
ํ ํ์ ์ ๋ค๋ฅธ ํ์ ์ผ๋ก ๋ณํํ๋ ๊ฒ. ๊ฐ์ฒด์งํฅ์์๋ ์ฃผ๋ก ์์ ๊ด๊ณ์์ ์ฌ์ฉ๋จ. ์ฆ, ๋ถ๋ชจ ํด๋์ค ↔ ์์ ํด๋์ค ๊ฐ์ ํ ๋ณํ์ ์๋ฏธํ๋ค.
์ ์บ์คํ
val dog = Dog()
// "as" ์์ด ์
์บ์คํ
(์์์ )
val animal: Animal = dog
animal.sound()
์์ ํด๋์ค์ ๊ฐ์ฒด(์ธ์คํด์ค)๋ฅผ ๋ถ๋ชจ ํด๋์ค ํ์ ์ผ๋ก ํ ๋ณํํ๋ ํ์. ํญ์ ์์ ํ๋ฉฐ ์๋์ผ๋ก(= ์์์ ์ผ๋ก) ์ํํ ์ ์๋ค.
๋ค์ด์บ์คํ
val animal: Animal = Cat()
// ๋ค์ด์บ์คํ
(๋ช
์์ ). "as"์์,
// ClassCastException ๋ฐ์ ๊ฐ๋ฅ์ฑ ์์
val dog = animal as Dog
dog.bark()
๋ถ๋ชจ ํด๋์ค์ ๊ฐ์ฒด(์ธ์คํด์ค)๋ฅผ ์์ ํด๋์ค ํ์ ์ผ๋ก ํ ๋ณํํ๋ ํ์. ์์ ์ด ๋ณด์ฅ๋์ง ์์ผ๋ฉฐ ๋ช ์์ ์บ์คํ ์ด ํ์ํ๋ค.
#5-3 ์๋ฌธ์ ?
์์์ ๋ถ๋ชจ์ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ํด์ ๋ง๋ค์ด์ง๋ฏ๋ก, ์ ์บ์คํ ์ด ๋ฌด์กฐ๊ฑด ๊ฐ๋ฅ(์์ )ํ๋ค. ์ฆ, ๋ฆฌ์ค์ฝํ ์นํ ์์น์ ์์์ ์ง์ผ์ง๋ ๊ฒ ์๋๊ฐ?
์๋๋ค. ํต์ฌ์ ์ ์บ์คํ ์ด ์๋๋ผ '๊ธฐ๋ฅ'์ด๋ค
open class Bird {
open fun fly() { println("๋ ์์") }
}
class Ostrich : Bird() {
// ์์์ด ๋ถ๋ชจ์ '๊ธฐ๋ฅ'(๋นํ) ์ํ ๋ถ๊ฐ
override fun fly() {
throw UnsupportedOperationException(
"ํ์กฐ๋ ๋ชป ๋ ์์"
)
}
}
๋ถ๋ชจ(Bird) ์ชฝ์์ fly() ๋ฉ์๋๋ฅผ ์ ์ํจ์ผ๋ก์จ ("์๋ ๋ ์ ์๋ค"๋ผ๋) '๊ธฐ๋ฅ'์ ๋ณด์ฅํ๋๋ฐ, ์์(Ostrich)์ด ๊ทธ ๋ณด์ฅ์ ๊นจ๋ฒ๋ ธ๋ค. ์ฆ, Ostrich๋ LSP๋ฅผ ์๋ฐํ๋ค. ํน์ ์ด๋ฐ ์ํฉ์ ๋ง๋ ํ๋ก๊ทธ๋๋จธ๊ฐ LSP๋ฅผ ์๋ฐํ๋ค.
#5-4 ์์ใ๊ธฐ๋ ํจ๊ณผ
LSP๋ฅผ ์งํจ ์์
์๋ฐ์ LinkedList, ArrayList, HashSet ๋ฑ์ ๋ชจ๋ Collection ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ์๋ฃํ์ Collection ํ์ ์ผ๋ก์ ๋ค๋ฃจ๋๋ผ๋ (= ์ ์บ์คํ ), Collection.add() ๋ Collection.contains() ๊ฐ์ ๋ฉ์๋๊ฐ ์ ์์ ์ผ๋ก(= ํ๋ก๊ทธ๋๋จธ๊ฐ ๊ธฐ๋ํ๋ ๋ ผ๋ฆฌ์ '๊ธฐ๋ฅ'์ ๋ง๊ฒ) ๋์ํ๋ฏ๋ก LSP๋ฅผ ์งํจ ์ฌ๋ก๋ผ๊ณ ํ ์ ์๋ค.
LSP๋ฅผ ์งํค์ง ์์ ์์
๋ฐ๋ฉด ๋ฐํ์ ์๋ฌ๊ฐ ๋์ง ์๋๋๋ add(), contains() ๋ฑ์ ๋์์ด ๋ ผ๋ฆฌ์ ์ผ๋ก ์ด์ํ๋ค๋ฉด, ๊ทธ๊ฒ์ LSP๋ฅผ ์๋ฐํ ๊ฒ์ด๋ค.
๊ธฐ๋ ํจ๊ณผ
LSP ํจํด์ ์ค์ํ์ฌ, ๊ฐ์ฒด์ ๊ตฌ์ฒด์ ์ธ(= ๋คํ์ ์ธ) ๊ตฌํ์ ์์กดํ์ง ์๊ฒ ๋ง๋ ๋ค. ๊ทธ๋์ ๊ฐ์ฒด ๊ต์ฒด๋ฅผ ์์ ๋ก์ด ๋ง๋ ๋ค. (๋คํ์ฑPolymorphism ↑).
#6 [I] ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น
Interface Segregation Principle, ISP
#6-1 What
ํด๋ผ์ด์ธํธ๊ฐ ํ์ ์๋ ๊ธฐ๋ฅ์ ์์กด(implement)ํ์ง ์๊ฒ, ์์กดํ ์ธํฐํ์ด์คใํด๋์ค ๊ตฌ์กฐ๋ฅผ ์ ๋๋ ์ค๊ณํ๋ค.
* ํด๋ผ์ด์ธํธ(Client): ์ธํฐํ์ด์ค๋ ๋ค๋ฅธ ํด๋์ค์ ๊ธฐ๋ฅ์ ๋์ด๋ค ์ฐ๋ ํด๋์ค (์ ํํ ๋น์ ๋ ์๋์ง๋ง, ํด๋์ค ๊ณ์ getter ๋๋)
๊ฐ์ฒด๋ ์ค์ง ์์ ์ด ํ์ํ '์ถ์'(#4-2, #4-4)์๋ง ์์กดํด์ผ ํ๋ค. ์ถ์ํ๋ฅผ ์ ์ํ๋ ๊ฒ์ ์ธํฐํ์ด์ค์ด๋ฏ๋ก, ์ธํฐํ์ด์ค๋ฅผ ์ ๋ถ๋ฆฌํ๋ฉด ISP๊ฐ ์ง์ผ์ง ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ "์ ๋ถ๋ฆฌํ๋ค"๋ผ๋ ๊ฒ์ ์๋ฏธ๋ ๊ทธ์ ์กฐ๊ทธ๋งฃ๊ฒ ๋๋๋ฉด OK๋ผ๋ ๊ฒ ์๋๋ผ, '์ถ์'(#4-2, #4-4)์ ๋ง๊ฒ ์ ๋๋๋ผ๋ ์๊ธฐ๋ค.
#6-2 ์ฉ์ด ์ ๋ฆฌ
ํด๋์ค: ๊ตฌ์ฒด์ ์ธ ๊ธฐ๋ฅ ๊ตฌํ
์ธํฐํ์ด์ค: ๊ตฌํ ์์ด ๊ธฐ๋ฅใํ์๋ง์ ์ ์
ํด๋ผ์ด์ธํธ: ํด๋์ค / ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ์ฃผ์ฒด์ธ ๊ฐ์ฒด
#6-3 ์์ใ๊ธฐ๋ ํจ๊ณผ
ISP๋ฅผ ์งํจ ์์

Kiosk๊ฐ LotteriaOrderSystem ๋ฐ LotteriaBurgerMenu ๋์ OrderSystem ๋ฐ BurgerMenu์ ์์กดํ๋ ์ด์ ๋ DIP ์์น์ ์งํค๊ธฐ ์ํจ์ด๋ค. ๋ง์ฝ Kiosk๊ฐ BurgerMenu๊ฐ ์๋ FastfoodMenu๋ฅผ ์์๋ฐ๋ ๊ตฌ์กฐ์๋ค๋ฉด(= ์์กดํ๋ค๋ฉด = implement ํ๋ค๋ฉด) ํผ์ ๋ฉ๋ด์ ๋ํด์ "์ฃผ๋ฌธํ ์ ์๋ ๋ฉ๋ด์ ๋๋ค."๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋๋ฅผ ์ผ์ผ์ด ๊ท์ฐฎ๊ฒ ๋ฃ์ด์ฃผ์ด์ผ ํ์ ๊ฒ์ด๋ค.
๊ธฐ๋ ํจ๊ณผ
ISP ํจํด์ ์ค์ํ์ฌ, ์๋ฏธ ์๋ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๊ฒ ๋ง๋๋ ๊ตฌ์กฐ๋ฅผ ํ์ฑํ๋ค.
#6-4 ํฌํจ ๊ด๊ณ ์ ๋ฆฌ
"ISP๋ฅผ ์งํค๋ฉด SRP๊ฐ ๋ฐ๋ผ์จ๋ค." → โณ
ํญ์ ๊ทธ๋ ์ง ์์ง๋ง, ๋์ฒด๋ก ๋ง๋ค. ์ธํฐํ์ด์ค๊ฐ ์์ผ๋ฉด, ํด๋น ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ๋ ํด๋์ค๊ฐ ๊ตฌํํ ๊ธฐ๋ฅ๋ ์์ ํ๋ฅ ์ด ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋น์ฐํ '์ฑ ์์ด ํ ๊ฐ์ง์ผ ํ๋ฅ '๋ ๋์์ง๋ค. ์๋๋ 'ํญ์ ๊ทธ๋ ์ง ์์' ์ด์ ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํ ์ฝ๋๋ค (๋ฐ๋ก).
class FileManager : Readable, Writable {
override fun read(): String {
...
}
override fun write(data: String) {
...
}
}
'ํด๋ผ์ด์ธํธ'๋ก์์ FileManager๋ ์์ ์ด ์ฌ์ฉํ์ง ์๋ ๋ฉ์๋์ ์์กดํ์ง ์๋๋ค (ISP ์ค์). ํ์ง๋ง, 'ํด๋์ค'๋ก์์ FileManager๋ (๊ด์ ์ ๋ฐ๋ผ 'ํ์ผ ๊ด๋ฆฌ'๋ผ๋ ๋จ์ผ ์ฑ ์์ผ๋ก ๋ณผ ์๋ ์๊ธด ํ์ง๋ง) 'ํ์ผ ์ฝ๊ธฐ'์ 'ํ์ผ ์ฐ๊ธฐ'๋ผ๋ 2๊ฐ์ง ์ฑ ์์ ๋ณด์ ํ๋ค. ์ด ๊ด์ ์์๋ ํด๋์ค์ ์ ์ฌ์ ์ ๋ฐ์ดํธ ์ด์ ๊ฐ, "ํ์ผ ์ฝ๊ธฐ ๋ก์ง์ ์์ ํ ํ์๊ฐ ์์ ๋"์ "ํ์ผ ์ฐ๊ธฐ ๋ก์ง์ ์์ ํ ํ์๊ฐ ์์ ๋"์ 2์ข ๋ฅ์ด๋ฏ๋ก SRP๋ฅผ ์๋ฐํ๊ฒ ๋๋ค.
"SRP๋ฅผ ์งํค๋ฉด ISP๊ฐ ๋ฐ๋ผ์จ๋ค." → โ
interface Board {
fun write()
fun read()
fun update()
fun delete()
}
์์ ์ธํฐํ์ด์ค๊ฐ ์ง๋ ๊ธฐ๋ฅ์, '๊ฒ์๊ธ ์ด์ฉ'์ด๋ผ๋ '๋จ์ผ ์ฑ ์'์ผ๋ก ๋ณด๊ธฐ๋ก ๊ฐ์ (์ฝ์)ํ๊ณ ์๋์ ์ฝ๋๋ฅผ ์ฝ์ด๋ณด์.
class AdminUser : Board {
override fun write() {
println("๊ด๋ฆฌ์๊ฐ ๊ธ์ ์.")
}
override fun read() {
println("๊ด๋ฆฌ์๊ฐ ๊ธ์ ์ฝ์.")
}
override fun update() {
println("๊ด๋ฆฌ์๊ฐ ๊ธ์ ์์ ํจ.")
}
override fun delete() {
println("๊ด๋ฆฌ์๊ฐ ๊ธ์ ์ญ์ ํจ.")
}
}
class NormalUser : Board {
override fun write() {
println("์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ธ์ ์.")
}
override fun read() {
println("์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ธ์ ์ฝ์.")
}
override fun update() {
println(
"์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ธ์ ์์ ํจ."
)
}
// ํ์์๋ ๊ตฌํ์ ๊ฐ์๋นํจ (ISP ์๋ฐ)
override fun delete() {
throw UnsupportedOperationException(
"์ผ๋ฐ ์ฌ์ฉ์๋ ๊ฒ์๊ธ ์ญ์ ๋ถ๊ฐ."
)
}
}
NormalUser.delete()๋ ๋ช ์ ์ ๋ํ ๋ฐ๋ก๋ค.
#7 [D] ์์กด ์ญ์ ์์น
Dependency Inversion Principle, DIP
#7-1 ๋ถ์ ํํ ์ค๋ช
์ด๋ค ํด๋์ค์ ์์กด(์ฐธ์กฐ)ํ๋ ๋์ , ๊ทธ ํด๋์ค์ ๊ฐ๋ฅํ ๋์ ๋ถ๋ชจ(ํด๋์ค, ์ธํฐํ์ด์ค)์ ์์กด(์ฐธ์กฐ)ํ๋ค.
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ์์ ์ชฝ์ผ๋ก ๊ฐ์๋ก '๊ตฌํ'์ด ๊ฐํด์ง๊ณ , ๋ถ๋ชจ ์ชฝ์ผ๋ก ๊ฐ์๋ก '์ถ์ํ'๊ฐ ๊ฐํด์ง๋ ๊ตฌ์กฐ๊ฐ ์์ฐํ ํ์ฑ๋๋ค. ์ด๋ ๋๋๋ก ๋ด๊ฐ ๋ค๋ฃจ๋ ๊ฐ์ฒด๊ฐ ์์ ์ชฝ๋ณด๋ค๋ ๋ถ๋ชจ ์ชฝ์ ์์กดํ๊ฒ ๋ง๋ค์ด๋ผ. ๋ค์ ๋งํด, ๊ตฌํ๋ณด๋จ ์ถ์ํ์ ์์กดํ๊ฒ ๋ง๋ค์ด๋ผ. ๋น์ ํ์๋ฉด, '์์กด์ ์ ์บ์คํ (#5-2)'์ ํ๋ผ๋ ๋ง์ด๋ค. ์์กด ๊ด๊ณ๋ฅผ ๋งบ์ ๋ ๋ณํํ๊ธฐ ์ฌ์ด ๊ฒ ๋๋ ์์ฃผ ๋ณํํ๋ ๊ฒ๋ณด๋ค๋, ๋ณํํ๊ธฐ ์ด๋ ค์ด ๊ฒ ๊ฑฐ์ ๋ณํ๊ฐ ์๋ ๊ฒ์ ์์กดํ๋ผ๋ ๊ฒ์ด๊ธฐ๋ ํ๋ค.
์์ ์ค๋ช ์ ์ดํด ๋์ด๋ ์ธก๋ฉด์์, ๊ทธ๋ฆฌ๊ณ 'DIP๊ฐ ๋์ถฉ ์ด๋ค ๋๋์ธ์ง' ํ์ ํ๊ธฐ์๋ ์ข๋ค. ํ์ง๋ง (๋ด๊ฐ ์ด ๊ฑฐ์ง๋ง) DIP๋ฅผ ๋ถ์ ํํ๊ฒ ์๊ณกํ ์ค๋ช ์ด๋ค. #7-3์์ ์ด์ด์ ์ค๋ช ํ๋ค.
#7-2 '์ญ์ '์ ์๋ฏธ
์๋ ํ๋ก๊ทธ๋๋ฐ์ ์ ์: ๊ณ ์์ค ๋ก์ง์ด ์ ์์ค ์ ํธ๋ฆฌํฐ๋ฅผ ํธ์ถ(์์กด)ํ๋ ๊ฒ ์์ฐ(์ง๊ด)์ค๋ฝ๋ค
↓
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ๋์ ํ ์ ์: ์ ์์ค ๊ตฌํ์ด ๊ณ ์์ค์ ์ถ์ ์ ์ฑ ์ ๋ฐ๋ฅด๋(์์กดํ๋) ๊ฒ (์ ์ง๋ณด์ ์) ํธํ๋ค
[์์ ๋ชจ๋ → ํ์ ๋ชจ๋]์์ [ํ์ ๋ชจ๋ → ์์ ๋ชจ๋]๋ก ์์กด ๋ฐฉํฅ์ ์ ์(ํจ๋ฌ๋ค์)์ด ์ญ์ ๋๋ค๋ ์๋ฏธ๋ค. ์ด์ด์ง๋ #7-3์์ '์ญ์ '์ ๋ ์ง๊ด์ ์ธ ์๋ฏธ๋ฅผ '๋ณด์ฌ'์ฃผ๊ฒ ๋ค.
#7-3 What (์ ํํ ์ค๋ช )
#7-1์ ์ค๋ช ์ด ๋ถ์ ํํ ์ด์ ๋ฅผ ๋์ดํด ๋ณด๊ฒ ๋ค.
"๋ถ๋ชจ์ ์์กดํ๋ผ." → โ
ํ๋ก๊ทธ๋๋ฐ์์ '๋ถ๋ชจ'๋ ์๋ '์์ ๊ด๊ณ'์์์ ์์ ํด๋์ค๋ฅผ ์๋ฏธํ๋ค. ์๋๋ DIP์ ์๋ฌธ์ด๋ค.
A. High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).
B. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
DIP์ ์๋ฌธ์์ ์ถ์(= ๊ตฌ์กฐ = ์ ์ฑ = ์ธํฐํ์ด์ค)์ ์์กดํ๋ผ๊ณ ํ๋ค. ์ด๋ฅผ '๋ถ๋ชจ'๋ผ๊ณ ๋ถ๋ฌ์ ์ ๋๋ค. ๋ฌผ๋ก ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ (์์ ๊ด๊ณ์์) ์์ ์ชฝ์ผ๋ก ๊ฐ์๋ก '๊ตฌํ'์ด ๊ฐํด์ง๊ณ , ๋ถ๋ชจ ์ชฝ์ผ๋ก ๊ฐ์๋ก '์ถ์ํ'๊ฐ ๊ฐํด์ง๋ ๊ตฌ์กฐ๊ฐ ์์ฐํ ํ์ฑ๋๋ค. ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ๋ถ๋ฅผ๋งํ ๊ฒฝํฅ์ฑ ์์ฒด๋ ์กด์ฌํ๋ค. ๊ทธ๋ ๋ค, ๊ทธ์ '๊ฒฝํฅ์ฑ'์ ๋ถ๊ณผํ ๊ฒ์ด๋ค.
"๋ถ๋ชจ(์ธํฐํ์ด์ค)" → โ
์ด๋ค ์ธํฐํ์ด์ค A๋ฅผ ๊ตฌํํ๋ ํด๋์ค B๊ฐ ์์ ๋, A๋ฅผ B์ '๋ถ๋ชจ'๋ผ๊ฑฐ๋ ๋ฐ๋๋ก B๋ฅผ A์ '์์'์ด๋ผ๊ณ ๋ถ๋ฅผ ์๋ ์๋ค. ์๋์ ์ฉ์ด ์ ๋ฆฌ๋ฅผ ๋ณด์.
์๋ธํ์ดํ(subtyping): B๊ฐ A๋ฅผ ๊ตฌํํ๊ฑฐ๋ ํ์ฅํ์ฌ, "A๋ฅผ ๊ธฐ๋ํ๋ ์์น(where A is expected)"์ B๋ฅผ ๋ฌ๋ ์์ ํ๊ฒ ๋์ฒด(substitute)๋๋ ๊ด๊ณ๋ก ๋ง๋๋ ๊ฒ (B๋ฅผ A์ subtype์ผ๋ก ๋ง๋๋ ํ์).
์์(inheritance): ๊ตฌํ(implementation)์ ๋ฌผ๋ ค๋ฐ์ผ๋ฉฐ ์๋ธํ์ดํํ๋ ๊ฒ.
์ธํฐํ์ด์ค ๊ตฌํ(implementation of interface): ์ธํฐํ์ด์ค๋ฅผ ์๋ธํ์ดํํ๋ ๊ฒ. ์ธํฐํ์ด์ค๋ ๊ฐ์ง ๊ตฌํ(implementation)์ด ์์ด, ์๋ธํ์ดํ ์ ๊ตฌํ์ ์๋ก ๋ง๋ค์ด์ผ๋ง ํ๋ฏ๋ก ์์์ด ์๋.
* ๊ทธ๋ ๋ค๋ฉด ์ธํฐํ์ด์ค๋ฅผ ์๋ธํ์ดํํด ์๋ก์ด ์ธํฐํ์ด์ค๋ฅผ ๋ง๋๋ ๊ฑด ๋ญ๋ผ๊ณ ๋ถ๋ฅผ๊น? ๋ฐ๋ก, '์ธํฐํ์ด์ค ํ์ฅ(interface extension)'์ด๋ผ ๋ถ๋ฅธ๋ค. ํ์ง๋ง ์ํค๋ฐฑ๊ณผ์ ๋ฐ๋ฅด๋ฉด ์ผ๋ถ์์ '์ธํฐํ์ด์ค ์์(interface inheritance)'์ด๋ผ๋ ํํ๋ ์ด๋ค๊ณ ํ๋ค. ํ์์ ๊ฒฝ์ฐ์ฌ๋, inheritance๋ผ๋ ๋จ์ด ์์ interface๋ผ๋ ๋จ์ด๊ฐ ์์ผ๋ฏ๋ก ํฌ๊ฒ ํท๊ฐ๋ฆด ์ผ๋ ค๋ ์์ ๊ฒ์ด๋ค.
๋ถ๋ชจ-์์ ๊ด๊ณ๋ ์์ ๊ด๊ณ๋ฅผ ์๋ฏธํ๋๋ฐ, ์ธํฐํ์ด์ค๋ ์์ ๊ด๊ณ๊ฐ ์๋๋ผ์ '๋ถ๋ชจ'๊ฐ ๋ ์ ์๋ค.
"๊ฐ๋ฅํ ๋์ ๋ถ๋ชจ์ ์ฑ
์ ์์กดํ๋ผ." → โ
'๋ถ๋ชจ'๋ผ๋ ๋ง์ ์์ ํ๋ฆฐ ์ด์ ๋ฅผ ์ค๋ช ํ์ผ๋, "๊ฐ๋ฅํ ๋์ ๋ถ๋ชจ์ ์์กดํ๋ผ"๋ผ๋ ํํ์ "๊ฐ๋ฅํ ๋์ ์ ์ฑ ์ ์์กดํ๋ผ"๋ก ๊ณ ์ณค๋ค. ๊ทธ๋ฌ๋ ์ด๋ ๊ฒ ๊ณ ์ณ๋ ํ๋ฆฐ ํํ์ด๋ค. ์๋ํ๋ฉด '๋์'์ด๋ผ๋ ๋จ์ด๋ ์์ ๊ด๊ณ์์๋ ์ฐ๋๊ฑฐ๋๊น. ๋ฐ๋ผ์ ์ด๋ ๊ฒ ๋งํด์ผ ํ๋ค: "๊ฐ๋ฅํ ์ ์ฑ ์ ์์กดํ๋ผ".
'์์ ๋ชจ๋ ๋ฐ ํ์ ๋ชจ๋'์ ๋ํ ์ธ๊ธ ์์ → โ
์๋ฌธ์๋ ์์ ๋ชจ๋์ด๋ ํ์ ๋ชจ๋์ ๋ํด "Both should depend on abstractions"๋ผ๊ณ ๋์ด ์๋ค. ๋ ๋ค ์ ์ฑ
์ ์์กดํ๋ผ๋ ์๊ธฐ๋ค. ์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์, ๋ฌด์์์ ์ผ๋ก ์์ ๋ชจ๋ํ๊ณ ํ์ ๋ชจ๋์ด ๋ถ๋ชจ-์์ ๊ด๊ณ๋ผ๊ณ ์ฐฉ๊ฐํ๋ ๊ฒ์ด๋ค. ๋ฌผ๋ก DIP ์ด์ ์ฆ, #7-2์ ์๋ '์๋ ํ๋ก๊ทธ๋๋ฐ์ ์ ์'๋๋ก๋ผ๋ฉด ๋ถ๋ชจ-์์ ๊ด๊ณ์ธ ๊ฒ์ด ์์ฐ์ค๋ฝ๋ค. '์๋ ํ๋ก๊ทธ๋๋ฐ์ ์ ์'๋๋ก์๋ค๊ณ ํ๋๋ผ๋ ๊ทธ๋ ๊ฒ ์ฐฉ๊ฐํด์ ์ ๋๋ค. ์๋ํ๋ฉด ์๋ ํ๋ก๊ทธ๋๋ฐ ๊ด์ ์์, '์์' ๋ชจ๋ํ๊ณ 'ํ์' ๋ชจ๋์ '์์กด์ฑ' ์ธก๋ฉด์์ ๊ตฌ๋ถํด ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค์ ์๋์ผ๋ก ์์กดํ๊ฒ ๋๋ ๊ฑด ๋ง์ง๋ง, ๋ฐ๋๋ก ์์กด์ฑ์ด ์๋ค๊ณ ๋ฐ๋์ ๋ถ๋ชจ-์์ ๊ด๊ณ์ธ ๊ฒ์ ์๋๋ค. ๊ฒฐ๋ก ์, ์๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ด์๋ค๋ฉด ์์กด์ฑ ๊ทธ๋ํ์์์ ์ด์ด์ ธ ์์์ ๋ ๋ชจ๋์ ์์กด์ฑ์ ์ ๊ฑฐํ๊ณ , ๋ ๋ชจ๋ '๊ฐ๊ฐ' ์ ์ฑ
์ ์์กด์ํค๋ผ๋ ๊ฒ์ด๋ค. ์ด๋ฅผ ์์กด์ฑ ๊ทธ๋ํ๋ก ํํํ๋ฉด ์๋์ ๊ฐ๋ค.

๊ทธ๋ํ 1์์๋ ํ์ดํ๊ฐ ์๋๋ก, ์ฆ ์์ ๋ ๋ฒจ ๋ชจ๋์์ ํ์ ๋ ๋ฒจ ๋ชจ๋๋ก ๋ด๋ ค๊ฐ์ง๋ง, ๊ทธ๋ํ 2๋ก ์ค๋ฉด์ ์์ ๋ ๋ฒจ ๋ชจ๋๊ณผ ํ์ ๋ ๋ฒจ ๋ชจ๋ ๊ฐ์ ์ง์ ์์กด์ด ์์ด์ง๋ฉด์ ๊ทธ๋ ์ง๋ง์ ์์์ก๋ค. ๊ทธ๋ํ 3์ ๊ทธ๋ํ 2์ (๋ ผ๋ฆฌ์ ์ผ๋ก) ์์ ํ ๋์ผํ ๊ทธ๋ํ์ธ๋ฐ, ํ์ดํ๊ฐ ์๋ฅผ ํฅํ๋๋ก '์ ์ฑ ' ๋ ธ๋์ ๋ฐฐ์น๋ง ๋ฐ๊พผ ๊ฒ์ด๋ค. ๊ทธ๋ํ 3์ฒ๋ผ '์ ์ฑ ' ๋ ธ๋๋ฅผ '๊ตฌํ' ๋ ธ๋๋ณด๋ค ์์ชฝ ๊ณต๊ฐ์ ๋ฐฐ์นํ๋ ๊ฒ ์๋ฌด ์ฌํญ์ ์๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์์ฐ์ค๋ฝ๋ค. ๋ง์น ์ด๋ค ๊ณํ์ด๋ ๊ฐ์ด๋๋ผ์ธ์ ๋จผ์ (= ์์์) ์ธ์ด ๋ค์์์์ผ ์ธ๋ถ ๊ตฌํ์ ์ง๋ ์ฐ๋ฆฌ๋ค์ ๋ชจ์ต์ด ๊ฒน์ณ ๋ณด์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ ๊ธฐ์ ๋๋ ๊ทธ๋ํ 3์ ๋ชจ์ต์ด '์ญ์ '์ ์ง๊ด์ ์ผ๋ก '๋ณด์ฌ'์ค๋ค๊ณ ์๊ฐํ๋ค. ์๋๋ก๋ง ํฅํ๋ ๊ทธ๋ํ 1์์ ํ์ดํ๊ฐ, ๊ทธ๋ํ 3์์๋ ๋ฐ๋๋ก ์ญ์ ๋์ด ์๋ก๋ง ํฅํ๊ณ ์๋ ๋ชจ์ต ๋ง์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ต์ข ์ผ๋ก, ์ ํํ ์ค๋ช ์?
์์ ๋ชจ๋์ ํ์ ๋ชจ๋(= "์ด๋ป๊ฒ ํด์ผ ํ๋๊ฐ?")์ ์ง์ ์์กดํ๋ ๋์ , ํ์ ๋ชจ๋์ด ์์กดํ๋ ์ถ์(์ธํฐํ์ด์ค, ์ ์ฑ )(= "๋ฌด์์ ํด์ผ ํ๋๊ฐ")์ ์์กดํ๋ค.
#7-4 ์์ใ๊ธฐ๋ ํจ๊ณผ
DIP๋ฅผ ์งํจ ์์

๋กฏ๋ฐ๋ฆฌ์๊ฐ ๋งฅ๋๋ ๋๋ฅผ ์ธ์ํ ์ธ๊ณ๊ฐ ์กด์ฌํ๋ค๊ณ ํด๋ณด์. ๊ทธ๋ฆฌ๊ณ ์ด ์ธ๊ณ์์ ๋กฏ๋ฐ๋ฆฌ์ ์ธก์ ๋กฏ๋ฐ๋ฆฌ์ ๋งค์ฅ์์๋ ๋งฅ๋๋ ๋์ ํ๋ฒ๊ฑฐ๋ฅผ ์ ๊ณตํ๊ธฐ๋ก ํ๋ค. ๊ทธ๋์ ์ ๊ตญ ๋กฏ๋ฐ๋ฆฌ์ ๋งค์ฅ์ ์๋ ํค์ค์คํฌ ์ผ๋ถ๋ฅผ ๋งฅ๋๋ ๋ ๋ฉ๋ด ์ ์ฉ ํค์ค์คํฌ๋ก ๋ฐ๊พธ๊ธฐ๋ก ํ๋ค.
ํ์ง๋ง ํค์ค์คํฌ ๋ด๋น ํ๋ก๊ทธ๋๋จธ๋ ์๊ณ ์๋ค(?). ์๋ํ๋ฉด Kiosk ํด๋์ค๊ฐ LotteriaBurgerMenu๊ฐ ์๋, (DIP๋ฅผ ์ค์ํ์ฌ) BurgerMenu์ ์์กดํ๋๋ก ๋์๊ธฐ ๋๋ฌธ์ (๋น๊ต์ ) ์์ํ๊ฒ ๋งฅ๋๋ ๋ ๋ฉ๋ด์ฉ ํค์ค์คํฌ๋ก ์ ํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ธฐ๋ ํจ๊ณผ
DIP ํจํด์ ์ค์ํ์ฌ, ํด๋์ค ๊ฐ ๊ฒฐํฉ๋(Coupling)๋ฅผ ๋ฎ์ถ ์ ์๋ค.
#7-5 ํฌํจ ๊ด๊ณ ์ ๋ฆฌ
"DIP๋ฅผ ์งํค๋ฉด LSP๊ฐ ๋ฐ๋ผ์จ๋ค." ๋๋ "LSP๋ฅผ ์งํค๋ฉด DIP๊ฐ ๋ฐ๋ผ์จ๋ค." → โ
๋ ๋ค ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ๊ฑด ๋ง์ง๋ง, ์ด๋ ์ชฝ์ด ์ด๋ ์ชฝ์ ํฌํจํ๋ ๊ด๊ณ๋ ์๋๋ค. DIP๋ ์ถ์ ์ค์ฌ์ ์ค๊ณ ๊ตฌ์กฐ ํ๋ฆฝ์ ์ํจ์ด๊ณ , LSP๋ ์์ ๊ด๊ณ์ ํด๋์ค๋ค์ ์ถ์ '๊ธฐ๋ฅ'์ด ์ผ๊ด์ฑ์ ์ ์งํ๊ฒ ๋ง๋ค๊ธฐ ์ํจ์ด๋ค.
TMI: "LSP๋ฅผ ์งํค๋ฉด DIP๋ฅผ ์งํค๊ธฐ ์ฝ๋ค." → โ
'๊ตฌํ'(์์ ์ชฝ) ๋์ ''์ถ์'(๋ถ๋ชจ ์ชฝ)์ ์์กดํ๊ธฐ ์ํด์ (= DIP ์ค์), ์์์ ์ค์ ๋ก ๋ถ๋ชจ๋ก ๋์ฒด ๊ฐ๋ฅ(= LSP ์ค์)ํด์ผ๋ง ์๋ฏธ๊ฐ ์๊ฒ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
'๊นจ์ ๊ฐ๋ ๐ > ๊ธฐํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| SCSS์ ์๋ํ (0) | 2025.12.23 |
|---|---|
| ์์กด์ฑ ๊ทธ๋ํ(Dependency graph), ๋ฐ์ดํฐ ํ๋ฆ๋(Data-flow diagram) (0) | 2025.12.11 |
| Gradle, ๋ฒ์ ์นดํ๋ก๊ทธ (0) | 2025.11.26 |
| Maven, Artifact, GAV (0) | 2025.11.25 |
| [Kotlin] Coroutines Flow - Cold Flow์ Hot Flow (SharedFlow) (0) | 2024.08.07 |