๋ก๋ฒํธ ๋งํด (Robert C. Martin)์ด 2000๋
๋ ์ด๋ฐ์ ๋ช
๋ช
ํ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ๋ฐ ์ค๊ณ์ ๋ค์ฏ ๊ฐ์ง ๊ธฐ๋ณธ ์์น ์ ๋ง์ดํด ํ๋์ค (Michael C. Feathers)๊ฐ ๋๋ฌธ์์ด ๊ธฐ์ต์ ๋ก ์๊ฐํ ๊ฒ์ด๋ค. ํ๋ก๊ทธ๋๋จธ๊ฐ ์๊ฐ์ด ์ง๋๋ ์ ์ง ๋ณด์์ ํ์ฅ์ด ์ฌ์ด ์์คํ
์ ๋ง๋ค๊ณ ์ ํ ๋ ์ด ์์น๋ค์ ํจ๊ป ์ ์ฉํ ์ ์๋ค.
๋ชฉ์ฐจ
SOLID (๊ฐ์ฒด ์งํฅ ์ค๊ณ )
Single responsibility principle, SRP
Open/closed principle, OCP
Liskov substitution principle, LSP
Interface segregation principle, ISP
Dependency inversion principle, DIP
๐ SOLID (๊ฐ์ฒด ์งํฅ ์ค๊ณ)
์ปดํจํฐ ํ๋ก๊ทธ๋๋ฐ์์ SOLID ๋ ๋ก๋ฒํธ ๋งํด (Robert C. Martin)์ด 2000๋
๋ ์ด๋ฐ์ ๋ช
๋ช
ํ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ๋ฐ ์ค๊ณ์ ๋ค์ฏ ๊ฐ์ง ๊ธฐ๋ณธ ์์น ์ ๋ง์ดํด ํ๋์ค (Michael C. Feathers)๊ฐ ๋๋ฌธ์์ด ๊ธฐ์ต์ ๋ก ์๊ฐํ ๊ฒ์ด๋ค. ํ๋ก๊ทธ๋๋จธ๊ฐ ์๊ฐ์ด ์ง๋๋ ์ ์ง ๋ณด์์ ํ์ฅ์ด ์ฌ์ด ์์คํ
์ ๋ง๋ค๊ณ ์ ํ ๋ ์ด ์์น๋ค์ ํจ๊ป ์ ์ฉํ ์ ์๋ค. SOLID ์์น๋ค์ ์ํํธ์จ์ด ์์
์์ ํ๋ก๊ทธ๋๋จธ๊ฐ ์์ค ์ฝ๋๊ฐ ์ฝ๊ธฐ ์ฝ๊ณ ํ์ฅํ๊ธฐ ์ฝ๊ฒ ๋ ๋๊น์ง ์ํํธ์จ์ด ์์ค ์ฝ๋๋ฅผ ๋ฆฌํฉํฐ๋งํ์ฌ ์ฝ๋ ๋์๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด ์ ์ฉํ ์ ์๋ ์ง์นจ์ด๋ค. ์ด ์์น๋ค์ ์ ์์ผ ์ํํธ์จ์ด ๊ฐ๋ฐ๊ณผ ์ ์์ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ์ ๋ฐ์ ์ ๋ต์ ์ผ๋ถ์ด๋ค.
โ๏ธ ๋จ์ผ ์ฑ
์ ์์น (Single responsibility principle, SRP)
: ํ ํด๋์ค๋ ํ๋์ ์ฑ
์๋ง ๊ฐ์ ธ์ผ ํ๋ค.
โ๏ธ ๊ฐ๋ฐฉ-ํ์ ์์น (Open/closed principle, OCP)
: ์ํํธ์จ์ด ์์๋ ํ์ฅ์๋ ์ด๋ ค ์์ผ๋ ๋ณ๊ฒฝ์๋ ๋ซํ ์์ด์ผ ํ๋ค.
โ๏ธ ๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov substitution principle, LSP)
: ํ๋ก๊ทธ๋จ์ ๊ฐ์ฒด๋ ํ๋ก๊ทธ๋จ์ ์ ํ์ฑ์ ๊นจ๋จ๋ฆฌ์ง ์์ผ๋ฉด์ ํ์ ํ์
์ ์ธ์คํด์ค๋ก ๋ฐ๊ฟ ์ ์์ด์ผ ํ๋ค. ๊ณ์ฝ์ ์ํ ์ค๊ณ๋ฅผ ์ฐธ๊ณ ํ๋ผ.
โ๏ธ ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface segregation principle, ISP)
: ํน์ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ์ธํฐํ์ด์ค ์ฌ๋ฌ ๊ฐ๊ฐ ๋ฒ์ฉ ์ธํฐํ์ด์ค ํ๋๋ณด๋ค ๋ซ๋ค. ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฒด์ ์ด๊ณ ์์ ๋จ์๋ก ๋ถ๋ฆฌํ์ฌ ๊ผญ ํ์ํ ์ธํฐํ์ด์ค๋ง ์์ํด์ผ ํ๋ค.
โ๏ธ ์์กด๊ด๊ณ ์ญ์ ์์น (Dependency inversion principle, DIP)
: ํ๋ก๊ทธ๋๋จธ๋ ์ถ์ํ์ ์์กดํด์ผ์ง, ๊ตฌ์ฒดํ์ ์์กดํ๋ฉด ์๋๋ค. ์์กด์ฑ ์ฃผ์
์ ์ด ์์น์ ๋ฐ๋ฅด๋ ๋ฐฉ๋ฒ ์ค ํ๋์ด๋ค. ์์ ๋ชจ๋์ ํ์ ๋ชจ๋์ ์์กดํ๋ฉด ์๋๋ค.
Single Responsibility Principle, SRP
• ๋จ์ผ ์ฑ
์ ์์น
• “ There should never be more than one reason for a class to change. ”
• ํ ํด๋์ค๋ ํ๋์ ์ฑ
์ (axis of change)๋ง ๊ฐ์ ธ์ผ ํ๋ค.
• ์ด๋ค ๋ณํ์ ์ํด ํด๋์ค๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๋ ์ด์ ๋ ์ค์ง ํ๋ ๋ฟ ์ด์ด์ผ ํ๋ค.
• ์ฑ
์์ “ ์บก์ํ ” ํ๋ค.
•. ์์ง๋ (Cohesion)๋ฅผ ๋์ด๊ณ ๊ฒฐํฉ๋ (Coupling)๋ฅผ ๋ฎ์ถ๋ค.
• ๊ฐ๋
์ฑ์ด ํฅ์๋๊ณ , ์ ์ง๋ณด์๊ฐ ์ฉ์ดํด์ง๋ค.
• ๋ค๋ฅธ ์์น๋ค์ ์ ์ฉํ๋ ๊ธฐ์ด๊ฐ ๋๋ค.
๐ Extract Class
Extract Class๋ ๋งํด ํ์ธ๋ฌ์ ์ฑ
<Refactoring: Improving the Design of Existing Code>2์์ ์๊ฐ๋ ํด๋์ค๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฐ์ฒด์งํฅ ๋ฆฌํฉํ ๋ง ์ ํ ๋ฐฉ๋ฒ์ด๋ค. ์ด ์ฑ
์์ ์๊ฐํ๋ ๋๋ถ๋ถ์ ์ํ์ํฉ์ ๋ํ ํด๊ฒฐ๋ฐฉ๋ฒ์ ์ง/๊ฐ์ ์ ์ผ๋ก SRP ์๋ฆฌ์ ๊ด๋ จ์ด ์๋ค. ํญ์ ์ฝ๋๋ฅผ ์ต์์ผ๋ก ์ ์งํ๋ค๋ ๋ฆฌํฉํ ๋ง์ ๊ทผ๋ณธ์ ์ ๋ ํญ์ ๊ฐ์ฒด๋ค์ ์ฑ
์์ ์ต์์ ์ํ๋ก ๋ถ๋ฐฐํ๋ค๋ ๊ฒ์์ ๋น๋กฏ๋๊ธฐ ๋๋ฌธ์ด๋ค. Extract Class๋ ๋ ๊ฐ์ ํด๋์ค๊ฐ ํด์ผ ํ ์ผ์ ํ๋์ ํด๋์ค๊ฐ ํ๊ณ ์๋ ๊ฒฝ์ฐ, ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ์์ ํด๋์ค์์ ์๋ก์ด ํด๋์ค๋ก ์ฎ๊ธฐ๋ ๊ฒ์ ์๋ฏธํ๋ค. ๊ฐ์ฒด์งํฅ ์ค๊ณ์์ ํด๋์ค๋ ๋ถ๋ช
ํ ์ถ์ํ๋์ด์ผ ํ๊ณ , ๋ช
ํํ ์ฑ
์์ ๊ฐ์ ธ์ผ ํ๋ค.
Move Method
๋ฉ์๋๊ฐ ์์ ์ด ์ ์๋ ํด๋์ค๋ณด๋ค ๋ค๋ฅธ ํด๋์ค์ ๊ธฐ๋ฅ์ ๋ ๋ง์ด ์ฌ์ฉํ๊ณ ์๋ค๋ฉด, ์ด ๋ฉ์๋๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๊ณ ์๋ ํด๋์ค์ ๋น์ทํ ๋ชธ์ฒด๋ฅผ ๊ฐ์ง ์๋ก์ด ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ , ์ด์ ๋ฉ์๋๋ ๊ฐ๋จํ ์์์ผ๋ก ๋ฐ๊พธ๊ฑฐ๋ ์์ ํ ์ญ์ ํ๋ค.
Move Field
ํ๋๊ฐ ์์ ์ด ์ ์๋ ํด๋์ค๋ณด๋ค ๋ค๋ฅธ ํด๋์ค์ ์ํด ๋ ๋ง์ด ์ฌ์ฉ๋๊ณ ์๋ค๋ฉด, ํ๊ฒ ํด๋์ค์ ์๋ก์ด ํ๋๋ฅผ ๋ง๋ค๊ณ ๊ธฐ์กด ํ๋๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ๋ถ๋ถ์ ๋ณ๊ฒฝํ๋ค.
Open Closed Principle, OCP
• ๊ฐ๋ฐฉ ํ์์ ์์น
• “ You should be able to extend a classes behavior, without modifying it. ”
• ์ํํธ์จ์ด๋ ํ์ฅ์๋ ์ด๋ ค ์์ด์ผ ํ๊ณ , ๋ณ๊ฒฝ์๋ ๋ซํ ์์ด์ผ ํ๋ค.
•. ์๊ตฌ์ฌํญ์ ๋ณ๊ฒฝ์ด๋ ์ถ๊ฐ์ฌํญ์ด ๋ฐ์ํ๋๋ผ๋ ๊ธฐ์กด ๊ตฌ์ฑ์์์๋ ์์ ์ด ์ผ์ด๋์ง ์์์ผ ํ๋ค.
• ์ฝ๊ฒ ํ์ฅ์ด ๊ฐ๋ฅํ์ฌ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋๋ก ๊ตฌ์ฑ๋์ด์ผ ํ๋ค.
• ๋ณํ๋ ๊ฒ์ ์จ๊ธฐ๊ณ ๋ณํ์ง ์๋ ๊ฒ์ ์์กด ํ๋ค.
• ๋ณํ๋ ๊ฒ๊ณผ ๋ณํ์ง ์๋ ๊ฒ์ ์๊ฒฉํ ๊ตฌ๋ถํ๋ค.
• ๊ด๋ฆฌ์ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ๋ง๋๋ ๊ธฐ๋ฐ์ด ๋๋ค.
• “ ์ถ์ํ ”๋ OCP ์ ํต์ฌ์์์ด๋ค.
๊ฐ๋ฐฉ ํ์์ ์์น์ ๋ฒํ๋ํธ ๋ฉ์ด์ด (Bertrand Meyer)๊ฐ 1998๋
์ฑ
3์์ ์ ์ํ ๊ฐ๋
์ด๋ค. ์ํํธ์จ์ด ๊ตฌ์ฑ์์ (์ปดํฌ๋ํธ, ํด๋์ค, ๋ชจ๋, ํจ์)๋ ํ์ฅ์๋ ์ด๋ ค์๊ณ , ๋ณ๊ฒฝ์๋ ๋ซํ์์ด์ผ ํ๋ค๋ ์๋ฆฌ์ด๋ค. ์ฆ, ๋ณ๊ฒฝ์ ์ํ ๋น์ฉ์ ๊ฐ๋ฅํ ์ค์ด๊ณ , ํ์ฅ์ ์ํ ๋น์ฉ์ ๊ฐ๋ฅํ ๊ทน๋ํ ํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค. ๋ฒํ๋ํธ ๋ฉ์ด์ด๋ ์ด ์์น์ ์ ์ฉํ๊ธฐ ์ํด ์์์ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ํ๋ค. ํ์ง๋ง ์์์ ์๋ธ ํด๋์ค๊ฐ ๊ตฌํ์ ์์กดํ๋ ๊ฒฝ์ฐ ์ํผ ํด๋์ค์ ์ธ๋ถ ์ ๋ณด์ ๊ธด๋ฐํ ๊ฒฐํฉํ๋ค. ๋ฐ๋ผ์, SOLID ์์น์ ์ ๋ฆฌํ ๋ก๋ฒํธ ๋งํด (Robert C. Martin)์ ๊ฐ๋ฐฉ ํ์์ ์์น์ ์ธํฐํ์ด์ค ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ (behavior)๋ฅผ ์ ์ํ๊ณ , ์ ์๋ ์ฝ๋๋ฅผ ์ฝ๊ฒ ๋์ฒดํ ์ ์๋ ๋ค์ํ ๊ตฌํ์ ํ์ฉํ๋๋ก ํ์๋ค. ๋ํ, OCP์ ์ฃผ์ํ ๋ฉ์ปค๋์ฆ์ ์ถ์ํ์ ๋คํ์ฑ์ด๋ผ๊ณ ํ์๋ค.
๐ ๊ทธ๋๋ ๋ถ์น (Grady Booch)๊ฐ ๋งํ๋ ์ถ์ํ๋ ?
๋ค๋ฅธ ๋ชจ๋ ์ข
๋ฅ์ ๊ฐ์ฒด๋ก๋ถํฐ ์๋ณ๋ ์ ์๋ ๊ฐ์ฒด์ ๋ณธ์ง์ ์ธ ํน์ง์ด๋ค.
Liskov Substitution Principle, LSP
• ๋ฆฌ์ค์ฝํ ์นํ ์์น
• “ Functions that use pointers or references to base classes must be able to use objects of derived objects of derived classes without knowing it. ”
• Sub type์ ์ธ์ ๋ Super type์ ๋์ฒดํ ์ ์์ด์ผ ํ๋ค.
• ๊ณ์ฝ์ ์ํ ์ค๊ณ (Design by Contract)์ ์ ์ฌ์ฑ์ ์ง๋๋ค.
• OCP๋ฅผ ์๋ฐํ์ง ์๋๋ก ํ๋ ๊ธฐ๋ฐ ์์น์ด๋ค.
• ํ๋์ ํ์ํ (Behavioral Subtype) : ๊ฐ์ฒด์ ๋ํ ๋์ฒด ๊ฐ๋ฅ์ฑ (Notion of substitutability for object)์ ์ ์ํ๋ค.
• LSP๋ฅผ ์๋ฐํ๋ ์ ํ์ ์ธ ์๋ก Circle-ellipse Problem์ด ์๋ค.
๐ Signature ์๊ตฌ์ฌํญ
• ์๋ธ ํ์
์์ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ ํ์
์ ๋ฐ๊ณต๋ณ์ฑ (Contravariance)
• ์๋ธ ํ์
์์ ๋ฉ์๋ return ํ์
์ ๊ณต๋ณ์ฑ (Covariance)
• ์๋ธ ํ์
์์ ๋ฉ์๋๋ ์์ ํด๋์ค์ ๋ฉ์๋์์ throwํ ํ์ํ์ ์ ์ธํ๊ณ ์๋ก์ด ์์ธ๋ฅผ ๋์ง ์๋ ์๋ค.
๐ Sub type์ ํ๋ ์กฐ๊ฑด
• ์๋ธ ํ์
์์ ์ ํ ์กฐ๊ฑด (pre-condition)์ ๊ฐํ๋ ์ ์๋ค.
• ์๋ธ ํ์
์์ ํํ ์กฐ๊ฑด (Post-condition)์ ์ฝํ๋ ์ ์๋ค.
• ์๋ธ ํ์
์์ ์ํผ ํ์
์ ๋ถ๋ณํ์ ๋ฐ๋์ ์ ์ง๋์ด์ผ ํ๋ค.
• ์ด๋ ฅ ์ ์ฝ ์กฐ๊ฑด (History constraint - History rule)
• ๊ฐ์ฒด๋ ๊ทธ ์์ ์ ๋ฉ์๋๋ฅผ ํตํด์๋ง ์์ (์บก์ํ) ๋ ์ ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋๋ค.
• ๋ฐ๋ผ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ ์ง์ (mutable point)์ ๋ณ๊ฒฝ ๋ถ๊ฐ ์ง์ (immutable point)์ ์๋ธ ํ์
์ผ๋ก ๋ง๋ ๋ค.
๐ ๊ณต๋ณ์ฑ (Convariance)์ ๋ฐ๊ณต๋ณ์ฑ (Contravariance)
• ๊ณต๋ณ์ฑ : ํ ๋ณ์๊ฐ ๋ณํ๋ฉด ๋ค๋ฅธ ๋ณ์๋ ๋ณํ๋ ์ฑ์ง
• ๋ฐ๊ณต๋ณ์ฑ : ๊ทธ ๋ฐ๋์ ์ฑ์ง
Interface Segregation Principle, ISP
• ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น
• “ Clients should not be foreced to depend upon interfaces that they do not use. ”
• ๋ฒ์ฉ ์ธํฐํ์ด์ค๋ณด๋ค ํน์ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ์ธํฐํ์ด์ค ์ฌ๋ฌ ๊ฐ๋ฅผ ์ ์ธํ๋ค.
• ์์คํ
๋ด๋ถ ์์กด์ฑ์ ์ฝํ์์ผ ๋ฆฌํฉํ ๋ง, ์์ , ์ฌ๋ฐฐํฌ๋ฅผ ์ฝ๊ฒ ํ ์ ์๋๋ก ํ๋ค.
์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น์ ์์ ์ด ์ฌ์ฉํ์ง ์๋ ์ธํฐํ์ด์ค๋ ๊ตฌํํ์ง ๋ง์์ผ ํ๋ค๋ ์์น์ด๋ค. ์ฆ, ํ๋์ ํฐ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ๊ธฐ ๋ณด๋ค๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฒด์ ์ด๊ณ ์์ ๋จ์๋ค๋ก ๋ถ๋ฆฌ์์ผ ๊ผญ ํ์ํ ์ธํฐํ์ด์ค๋ง ์์ํ์๋ ์๋ฏธ์ด๋ค. SRP๋ ํด๋์ค์ ๋จ์ผ ์ฑ
์์ ๊ฐ์กฐํ๋ค๋ฉด ISP๋ ์ธํฐํ์ด์ค์ ๋จ์ผ ์ฑ
์์ ๊ฐ์กฐํ๋ค.
Dependency Inversion Principle, DIP
• ์์กด ๊ด๊ณ ์ญ์ ์์น
• “High level modules should not depend upon low level modules. Both should depend upon abstractions.”
• “Abstractions should not depend upon details. Details should depend upon abstractions.”
• ์ถ์ํ์ ์์กดํด์ผ ํ๊ณ , ๊ตฌ์ฒดํ์ ์์กดํ๋ฉด ์๋๋ค.
• ์์ ๋ชจ๋์ ํ์ ๋ชจ๋์ ์์กดํด์๋ ์๋๋ค.
• “์์์ ํ์ ๊ฐ์ฒด ๋ชจ๋ ๋์ผํ ์ถ์ํ์ ์์กดํด์ผ ํ๋ค”๋ ๊ฐ์ฒด์งํฅ ์ค๊ณ์ ๋์์น์ ์ ๊ณตํ๋ค.
์์กด ๊ด๊ณ ์ญ์ ์์น์ ์ถ์ํ์ ์์กดํ๊ณ , ์ธ๋ถ ์ฌํญ์ ์์กดํด์๋ ์๋๋ค๋ ์์น์ด๋ค. ํด๋์ค ์ฌ์ด์ ์์กด ๊ด๊ณ๋ ๋น์ฐํ ์กด์ฌํ์ง๋ง, ์ต๋ํ ์ถ์ํ๋ ํด๋์ค์ ์์กดํ๋ผ๋ ๊ฒ์ด๋ค. Java์ ์ธํฐํ์ด์ค์ ๊ฐ์ ํ์
์ ๊ธฐ๋ฐํ ์์ฉ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ผ๋ ์๋ฏธ์ด๊ธฐ๋ ํ๋ค. DIP์ ํค์๋๋ ‘IOS’, ‘ํ
๋ฉ์๋’, ‘ํ์ฅ์ฑ’์ด๋ค.
Reference
SOLID (๊ฐ์ฒด ์งํฅ ์ค๊ณ) - ์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์
์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์ . -->
ko.wikipedia.org
๊ฐ์ฒด์งํฅ ๊ฐ๋ฐ 5๋ ์๋ฆฌ: SOLID
ํ์ฌ๋ฅผ ์ด์๊ฐ๋ ์ฐ๋ฆฌ๋ค์ ๋ชจ๋ ์ผ์ ํ ์๋ฆฌ/์์น ์๋์์ ์ํํ๊ณ ์์ต๋๋ค. ์ฌ๊ธฐ์์ ์์น ์ด๋ผ ํจ์ ์ข์ ์๋ฏธ๋ก๋ ๊ฐ๊ฐ์ธ์ ์ฌ๊ณ ๋ฐฉ์์ด๋ ์ ๋
, ๊ฐ์น๊ด ์ ๋๊ฐ ๋ ์๊ฐ ์๊ฒ ๊ณ , ๋๊ฒ๋ ํ
www.nextree.co.kr