BackEnd

쒋은 객체 지ν–₯ μ„€κ³„μ˜ 5가지 원칙(SOLID)

mokhs 2021. 6. 12. 23:39

κΉ€μ˜ν•œλ‹˜μ˜ μŠ€ν”„λ§ 핡심 원리 기본편 κ°•μ˜λ₯Ό 보고 μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

SOLID

ν΄λ¦°μ½”λ“œλ‘œ 유λͺ…ν•œ λ‘œλ²„νŠΈ λ§ˆν‹΄μ΄ 쒋은 객체 지ν–₯ μ„€κ³„μ˜ 5가지 원칙을 λ‹€μŒκ³Ό 같이 정리함.

  • SRP: 단일 μ±…μž„ 원칙(single responsibility principle)
  • OCP: 개방-폐쇄 원칙 (Open/closed principle)
  • LSP: λ¦¬μŠ€μ½”ν”„ μΉ˜ν™˜ 원칙 (Liskov substitution principle)
  • ISP: μΈν„°νŽ˜μ΄μŠ€ 뢄리 원칙 (Interface segregation principle)
  • DIP: μ˜μ‘΄κ΄€κ³„ μ—­μ „ 원칙 (Dependency inversion principle)

SRP 단일 μ±…μž„ 원칙

Single responsibility principle

  • ν•œ ν΄λž˜μŠ€λŠ” ν•˜λ‚˜μ˜ μ±…μž„λ§Œμ„ κ°€μ Έμ•Ό ν•œλ‹€.
    -> 사싀 λͺ¨ν˜Έν•˜λ‹€
  • ν•˜λ‚˜μ˜ μ±…μž„μ΄λΌλŠ” 것은 λͺ¨ν˜Έν•˜λ‹€.
    • μ±…μž„μ΄ 클 μˆ˜λ„, μž‘μ„ μˆ˜λ„ μžˆλ‹€
    • λ¬Έλ§₯κ³Ό 상황에 따라 λ‹€λ₯΄λ‹€.
  • μ€‘μš”ν•œ 기쀀은 변경이닀. 변경이 μžˆμ„ λ–„ νŒŒκΈ‰ νš¨κ³Όκ°€ 적으면 단일 μ±…μž„ 원칙을 잘 λ”°λ₯Έ 것
  • ex) UI λ³€κ²½, 객체의 생성과 μ‚¬μš©μ„ 뢄리

-> λ²”μœ„λ₯Ό μ μ ˆν•˜κ²Œ μ‘°μ ˆν•˜λŠ” 것이 객체 지ν–₯ μ„€κ³„μ˜ 묘미, 변경이 μžˆμ„ λ•Œ ν•˜λ‚˜μ˜ 클래슀의 ν•˜λ‚˜μ˜ λΆ€λΆ„λ§Œ κ³ μΉ  수 μžˆλŠ” 섀계라면 SRPλ₯Ό 잘 지킨 것!

OCP 개방-폐쇄 원칙

Open/closed principle

  • μ†Œν”„νŠΈμ›¨μ–΄ μš”μ†ŒλŠ” ν™•μž₯μ—λŠ” μ—΄λ €μžˆμœΌλ‚˜ λ³€κ²½μ—λŠ” λ‹«ν˜€ μžˆμ–΄μ•Ό ν•œλ‹€.
  • ν™•μž₯을 ν•˜λ €λ©΄, λ‹Ήμ—°νžˆ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•œλ‹€. 그럼 이건 지킬 수 μ—†λŠ” κ²ƒμΌκΉŒ?
  • μ•„λ‹ˆλ‹€. λ‹€ν˜•μ„±μ„ ν™œμš©ν•œλ‹€λ©΄ μ‰½κ²Œ 이λ₯Ό 이해할 수 μžˆλ‹€.
  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ μƒˆλ‘œμš΄ 클래슀λ₯Ό ν•˜λ‚˜ λ§Œλ“€μ–΄μ„œ μƒˆλ‘œμš΄ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν™•μž₯ν•˜λ©΄ λœλ‹€.

문제점

    // MemberRepository reopsitory = new JDBCMemberRepository();
    MemberRepository reopsitory = new JpaMemberRepository();
  • μœ„μ™€ 같이 κ΅¬ν˜„ 객체λ₯Ό λ³€κ²½ν•˜λ €λ©΄ κ²°κ΅­ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•œλ‹€.
  • λΆ„λͺ… λ‹€ν˜•μ„±μ„ μ‚¬μš©ν–ˆμ§€λ§Œ, OCP 원칙을 지킬 수 μ—†λ‹€.
  • 이 문제λ₯Ό μ–΄λ–»κ²Œ ν•΄κ²°ν•΄μ•Όν• κΉŒ?
  • 객체λ₯Ό μƒμ„±ν•˜κ³ , 연관관계λ₯Ό λ§Ίμ–΄μ£ΌλŠ” λ³„λ„μ˜ 쑰립, μ„€μ •μžκ°€ ν•„μš”ν•˜λ‹€.
  • 사싀 μŠ€ν”„λ§μ—μ„œλŠ” μ»¨ν…Œμ΄λ„ˆλ₯Ό μ΄μš©ν•΄μ„œ 이λ₯Ό ν•΄κ²°ν•œλ‹€.

LSP λ¦¬μŠ€μ½”ν”„ μΉ˜ν™˜ 원칙

Liskov substitution principle

  • ν”„λ‘œκ·Έλž¨μ˜ κ°μ²΄λŠ” ν”„λ‘œκ·Έλž¨μ˜ 정확성을 κΉ¨λœ¨λ¦¬μ§€ μ•ŠμœΌλ©΄μ„œ ν•˜μœ„ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ°”κΏ€ 수 μžˆμ–΄μ•Ό ν•œλ‹€.
  • λ‹€ν˜•μ„±μ—μ„œ ν•˜μœ„ ν΄λž˜μŠ€λŠ” μΈν„°νŽ˜μ΄μŠ€ κ·œμ•½μ„ λ‹€ μ§€μΌœμ•Ό ν•œλ‹€λŠ” 것이닀. λ‹€ν˜•μ„±μ„ μ§€μ›ν•˜κΈ° μœ„ν•œ 원칙, μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄λ₯Ό λ―Ώκ³  μ‚¬μš©ν•˜λ €λ©΄ 이 원칙이 ν•„μš”ν•˜λ‹€.
  • λ‹¨μˆœνžˆ μ»΄νŒŒμΌμ— μ„±κ³΅ν•˜λŠ” 것을 λ„˜μ–΄μ„œλŠ” 이야기
    -> μžλ™μ°¨λ₯Ό λ§Œλ“œλŠ”λ° 악셀을 밟으면 μ•žμœΌλ‘œ κ°€λŠ” κΈ°λŠ₯을 ν‘œμ€€μœΌλ‘œ λ§Œλ“€μ—ˆλ‹€κ³  치자 그런데 악셀을 밟으면 λ’€λ‘œ κ°€λŠ” κΈ°λŠ₯으둜 λ§Œλ“€μ—ˆλ‹€κ³  ν•΄λ³΄μž. 컴파일 μ‹œμ— λ¬Έμ œλŠ” λ˜μ§€ μ•Šμ§€λ§Œ LSP 원칙에 μ–΄κΈ‹λ‚œ 것이 λœλ‹€.
    이λ₯Ό μ •λ¦¬ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.
  • 예) μžλ™μ°¨ μΈν„°νŽ˜μ΄μŠ€μ˜ 엑셀을 μ•žμœΌλ‘œ κ°€λΌλŠ” κΈ°λŠ₯, λ’€λ‘œ κ°€κ²Œ κ΅¬ν˜„ν•˜λ©΄ LSP μœ„λ°˜, λŠλ¦¬λ”λΌλ„ μ•žμœΌλ‘œ κ°€μ•Όν•œλ‹€.

ISP μΈν„°νŽ˜μ΄μŠ€ 뢄리 원칙

Interface segregation principle

  • νŠΉμ • ν΄λΌμ΄μ–ΈνŠΈλ₯Ό μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€ μ—¬λŸ¬ κ°œκ°€ λ²”μš© μΈν„°νŽ˜μ΄μŠ€ ν•˜λ‚˜λ³΄λ‹€ λ‚«λ‹€.
  • μžλ™μ°¨ μΈν„°νŽ˜μ΄μŠ€ -> μš΄μ „ μΈν„°νŽ˜μ΄μŠ€, μ •λΉ„ μΈν„°νŽ˜μ΄μŠ€λ‘œ 뢄리
  • μ‚¬μš©μž ν΄λΌμ΄μ–ΈνŠΈ -> μš΄μ „μž ν΄λΌμ΄μ–ΈνŠΈ, 정비사 ν΄λΌμ΄μ–ΈνŠΈλ‘œ 뢄리
  • λΆ„λ¦¬ν•˜λ©΄ μ •λΉ„ μΈν„°νŽ˜μ΄μŠ€ μžμ²΄κ°€ 변해도 μš΄μ „μž ν΄λΌμ΄μ–ΈνŠΈμ— 영ν–₯을 주지 μ•ŠμŒ
  • μΈν„°νŽ˜μ΄μŠ€κ°€ λͺ…확해지고, λŒ€μ²΄ κ°€λŠ₯성이 높아진닀. -> 덩어리가 μž‘μ•„μ§€κΈ° λ•Œλ¬Έ
  • μŠ€ν”„λ§μ€ 정말 μ² μ €ν•˜κ²Œ μΈν„°νŽ˜μ΄μŠ€κ°€ λΆ„λ¦¬λ˜μ–΄ μžˆλ‹€κ³  함.

DIP μ˜μ‘΄κ΄€κ³„ μ—­μ „ 원칙

Dependency inversion principle

  • ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” "좔상화에 μ˜μ‘΄ν•΄μ•Όμ§€, ꡬ체화에 μ˜μ‘΄ν•˜λ©΄ μ•ˆλœλ‹€." μ˜μ‘΄μ„± μ£Όμž…μ€ 이 원칙을 λ”°λ₯΄λŠ” 방법 쀑 ν•˜λ‚˜λ‹€.
  • μ‰½κ²Œ μ΄μ•ΌκΈ°ν•΄μ„œ κ΅¬ν˜„ ν΄λž˜μŠ€μ— μ˜μ‘΄ν•˜μ§€ 말고, μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜λΌλŠ” 뜻!
  • ex) μ—­ν• (Role)에 μ˜μ‘΄ν•˜κ²Œ ν•΄μ•Όν•œλ‹€λŠ” 말(λ°°μš°μ™€ λ°°μ—­, λ°°μš°κ°€ 배껴도 배역은 λ³€ν•˜μ§€ μ•ŠμŒ)κ³Ό κ°™λ‹€.
  • 객체 세상도 ν΄λΌμ΄μ–ΈνŠΈκ°€ μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•΄μ•Ό μœ μ—°ν•˜κ²Œ κ΅¬ν˜„μ²΄λ₯Ό λ³€κ²½ν•  수 있음. κ΅¬ν˜„μ²΄μ— μ˜μ‘΄ν•˜κ²Œ 되면 변경이 μ•„μ£Ό μ–΄λ €μ›Œμ§!!!!

μ•„λž˜ μ½”λ“œμ˜ MemberServiceλŠ” μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜μ§€λ§Œ, κ΅¬ν˜„ ν΄λž˜μŠ€λ„ λ™μ‹œμ— μ˜μ‘΄ν•œλ‹€.

  • μ˜μ‘΄ν•œλ‹€ = ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ κ·Έ μ½”λ“œμ— λŒ€ν•΄ μ•Œκ³  μžˆλ‹€.
  • λ”°λΌμ„œ DIP μœ„λ°˜!
  • MemberService ν΄λΌμ΄μ–ΈνŠΈκ°€ κ΅¬ν˜„ 클래슀λ₯Ό 직접 μ„ νƒν•˜κ³  있음...
@Service
class MemberService {
    MemberRepository repository = new JpaMemberRepository();
}

정리

  • 객체 지ν–₯의 핡심은 λ‹€ν˜•μ„±
  • μ—­ν• κ³Ό κ΅¬ν˜„μ„ λΆ„λ¦¬ν•˜λΌ.
  • μœ μ—°ν•˜κ²Œ λ³€κ²½ν•  수 μžˆλ„λ‘ λ§Œλ“œλŠ” 것이 쒋은 객체 지ν–₯ 섀계닀.
  • μ΄μƒμ μœΌλ‘œ λͺ¨λ“  섀계에 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λΆ€μ—¬ν•˜μž.
  • ν•˜μ§€λ§Œ, λ‹€ν˜•μ„±λ§ŒμœΌλ‘œλŠ” μ‰½κ²Œ λΆ€ν’ˆμ„ κ°ˆμ•„ λΌμš°λ“―μ΄ κ°œλ°œν•  수 μ—†λ‹€..
  • λ‹€ν˜•μ„±λ§ŒμœΌλ‘œ κ΅¬ν˜„ 객체λ₯Ό λ³€κ²½ν•  λ•Œ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ„ ν•¨κ»˜ λ³€κ²½λœλ‹€.
  • λ‹€ν˜•μ„±λ§ŒμœΌλ‘œλŠ” OCP, DIPλ₯Ό 지킬 수 μ—†κ³ , λ­”κ°€ 더 ν•„μš”ν•˜λ‹€
  • 그것이 λ°”λ‘œ μŠ€ν”„λ§!! μŠ€ν”„λ§μ€ DIλ₯Ό 톡해 λ‹€ν˜•μ„± + OCP, DIPλ₯Ό κ°€λŠ₯ν•˜κ²Œ μ§€μ›ν•œλ‹€.
λ°˜μ‘ν˜•