πŸ“• [Object] 6μž₯. λ©”μ‹œμ§€μ™€ μΈν„°νŽ˜μ΄μŠ€

박상민·2024λ…„ 3μ›” 1일

Book

λͺ©λ‘ 보기
12/22
post-thumbnail

⭐️ λ“€μ–΄κ°€λ©°

자주 κ°•μ‘°ν•˜μ§€λ§Œ 객체지ν–₯ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ κ°€μž₯ μ€‘μš”ν•œ μž¬λ£ŒλŠ” ν΄λž˜μŠ€κ°€ μ•„λ‹Œ 객체듀이 μ£Όκ³ λ°›λŠ” λ©”μ‹œμ§€λ‹€.

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ 클래슀둜 κ΅¬μ„±λ˜μ§€λ§Œ λ©”μ‹œμ§€λ₯Ό 톡해 μ •μ˜λœλ‹€.

객체가 μˆ˜μ‹ ν•˜λŠ” λ©”μ‹œμ§€λ“€μ΄ 객체의 퍼블릭 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬μ„±ν•œλ‹€. ν›Œλ₯­ν•œ 퍼블릭 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ–»κΈ° μœ„ν•΄μ„œλŠ” μ±…μž„ 주도 섀계 방법을 λ”°λ₯΄λŠ” κ²ƒλ§ŒμœΌλ‘œλŠ” λΆ€μ‘±ν•˜λ‹€.
μœ μ—°ν•˜κ³  μž¬μ‚¬μš© κ°€λŠ₯ν•œ 퍼블릭 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“œλŠ” 데 도움이 λ˜λŠ” 섀계 원칙과 기법을 읡히고 μ μš©ν•΄μ•Ό ν•œλ‹€. 이런 원칙과 기법듀을 μ‚΄νŽ΄λ³΄λŠ” 것이 이번 μž₯의 μ£Όμ œμ΄λ‹€.

⭐️ ν˜‘λ ₯κ³Ό λ©”μ‹œμ§€

πŸ“Œ ν΄λΌμ΄μ–ΈνŠΈ - μ„œλ²„ λͺ¨λΈ

ν˜‘λ ₯은 μ–΄λ–€ 객체가 λ‹€λ₯Έ κ°μ²΄μ—κ²Œ 무언가λ₯Ό μš”μ²­ν•  λ•Œ μ‹œμž‘λœλ‹€. λ©”μ‹œμ§€λŠ” 객체 μ‚¬μ΄μ˜ ν˜‘λ ₯을 κ°€λŠ₯ν•˜κ²Œ ν•˜λŠ” λ§€κ°œμ²΄μ΄λ‹€.

ν˜‘λ ₯ μ•ˆμ—μ„œ λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ, λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•˜λŠ” μ„œλ²„λΌκ³  ν‘œν˜„ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ - μ„œλ²„ λͺ¨λΈμ΄ μžˆλ‹€.

  • Switch: ν΄λΌμ΄μ–ΈνŠΈ
  • Hitter: μ„œλ²„

Switcκ°€ Hitter에 μ˜¨λ„λ₯Ό 높이라고 μš”μ²­ν•˜λ©΄ HitterλŠ” μ—΄μ—λ„ˆμ§€λ₯Ό 주게 λœλ‹€.
이 같은 κ²½μš°λŠ” μš°λ¦¬κ°€ Rest API 톡신을 톡해 많이 κ²ͺ게 λ˜λŠ” 상황인데, ν”„λ‘ νŠΈμ™€ λ°±μ—”λ“œκ°€ λΆ„λ¦¬λœ μ„œλ²„μ—μ„œ 자주 마주칠 수 μžˆλŠ” 상황이닀.
HitterλŠ” 또 λ‹€λ₯Έ κ°μ²΄μ—κ²Œ ν΄λΌμ΄μ–ΈνŠΈ μž…μž₯으둜 μ‘΄μž¬ν•  수 μžˆλ‹€. κ°€λ Ή μ „κΈ° μ—λ„ˆμ§€λ₯Ό μ–»κΈ° μœ„ν•΄ λ‹€λ₯Έ 객체λ₯Ό 찾을 수 μžˆλ‹€.

πŸ“Œ λ©”μ‹œμ§€μ™€ λ©”μ‹œμ§€ 전솑

λ©”μ‹œμ§€(message)

  • κ°œμ²΄λ“€μ΄ ν˜‘λ ₯ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•  수 μžˆλŠ” μœ μΌν•œ μ˜μ‚¬μ†Œν†΅ μˆ˜λ‹¨
  • ν•œ 객체가 λ‹€λ₯Έ κ°μ²΄μ—κ²Œ 도움을 μš”μ²­ν•˜λŠ” 것을 λ©”μ‹œμ§€ 전솑(message sending) λ˜λŠ” λ©”μ‹œμ§€ νŒ¨μ΄μ‹±(message passing)라고 ν•œλ‹€.
    • μ΄λ•Œ λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•˜λŠ” 객체λ₯Ό λ©”μ‹œμ§€ μ „μ†‘μž(message sender)라고 λΆ€λ₯΄κ³  λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•˜λŠ” 객체λ₯Ό λ©”μ‹œμ§€ μˆ˜μ‹ μž(message receiver)라고 λΆ€λ₯Έλ‹€.
      • ν΄λΌμ΄μ–ΈνŠΈ - μ„œλ²„ λͺ¨λΈ κ΄€μ μ—μ„œλŠ” λ©”μ‹œμ§€ μ „μ†‘μžλŠ” ν΄λΌμ΄μ–ΈνŠΈ, λ©”μ‹œμ§€ μˆ˜μ§„μžλŠ” μ„œλ²„λΌκ³  λΆ€λ₯΄κΈ°λ„ ν•œλ‹€.
  • λ©”μ‹œμ§€λŠ” μ˜€νΌλ ˆμ΄μ…˜λͺ…(operation name)κ³Ό 인자(argument)둜 κ΅¬μ„±λœλ‹€.

λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν–ˆμ„ λ•Œ μ‹€μ œλ‘œ μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜ λ˜λŠ” ν”„λ‘œμ‹œμ €λ₯Ό λ©”μ„œλ“œλΌκ³  λΆ€λ₯Έλ‹€.

λ©”μ‹œμ§€μ™€ λ©”μ„œλ“œμ˜ ꡬ뢄은 λ©”μ‹œμ§€ μ „μ†‘μžμ™€ λ©”μ‹œμ§€ μˆ˜μ‹ μžκ°€ λŠμŠ¨ν•˜κ²Œ 결합될 수 있게 ν•œλ‹€. λ©”μ‹œμ§€ μ „μ†‘μžλŠ” μžμ‹ μ΄ μ–΄λ–€ λ©”μ‹œμ§€λ₯Ό 전솑해야 ν•˜λŠ”μ§€λ§Œ μ•Œλ©΄ λœλ‹€. μˆ˜μ‹ μžκ°€ μ–΄λ–€ 크래슀의 μΈμŠ€ν„΄μŠ€μΈμ§€, μ–΄λ–€ λ°©μ‹μœΌλ‘œ μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ”μ§€ λͺ¨λ₯΄λ”라도 μ›ν™œν•œ ν˜‘λ ₯이 κ°€λŠ₯ν•˜λ‹€. λ©”μ‹œμ§€ μˆ˜μ‹ μž μ—­μ‹œ λˆ„κ°€ λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•˜λŠ”μ§€ μ•Œ ν•„μš”κ°€ μ—†λ‹€. 단지 λ©”μ‹œμ§€κ°€ λ„μ°©ν–ˆλ‹€λŠ” μ‚¬μ‹€λ§Œ μ•Œλ©΄ λœλ‹€.

πŸ“Œ 퍼블릭 μΈν„°νŽ˜μ΄μŠ€μ™€ μ˜€νΌλ ˆμ΄μ…˜(operation)

퍼블릭 μΈν„°νŽ˜μ΄μŠ€

  • 객체가 μ˜μ‚¬μ†Œν†΅μ„ μœ„ν•΄ 외뢀에 κ³΅κ°œν•˜λŠ” λ©”μ‹œμ§€μ˜ μ§‘ν•©
    • 퍼블릭 μΈν„°νŽ˜μ΄μŠ€μ— ν¬ν•¨λœ λ©”μ‹œμ§€λ₯Ό μ˜€νΌλ ˆμ΄μ…˜(operation)이라고 λΆ€λ₯Έλ‹€.
      • μ˜€νΌλ ˆμ΄μ…˜μ€ μˆ˜ν–‰ κ°€λŠ₯ν•œ μ–΄λ–€ 행동에 λŒ€ν•œ 좔상화닀.

πŸ“Œ μ‹œκ·Έλ‹ˆμ²˜(signature)

μ‹œκ·Έλ‹ˆμ²˜(signature)

  • μ˜€νΌλ ˆμ΄μ…˜(λ˜λŠ” λ©”μ„œλ“œ)의 이름과 λͺ©λ‘μ„ ν•©μΉœ 것
    • μ˜€νΌλ ˆμ΄μ…˜μ€ μ‹€ν–‰ μ½”λ“œ 없이 μ‹œκ·Έλ‹ˆμ²˜λ§Œμ„ μ •μ˜ν•œ 것이닀. λ©”μ„œλ“œλŠ” 이 μ‹œκ·Έλ‹ˆμ²˜μ— κ΅¬ν˜„μ„ λ”ν•œ 것이닀. 일반적으둜 λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•˜λ©΄ μ˜€νΌλ ˆμ΄μ…˜μ˜ μ‹œκ·Έλ‹ˆμ²˜μ™€ λ™μΌν•œ λ©”μ„œλ“œκ°€ μ‹€ν–‰λœλ‹€.

⭐️ μΈν„°νŽ˜μ΄μŠ€ 섀계 ν’ˆμ§ˆ

쒋은 μΈν„°νŽ˜μ΄μŠ€

  • μ΅œμ†Œν•œμ˜ μΈν„°νŽ˜μ΄μŠ€
  • 좔상적인 μΈν„°νŽ˜μ΄μŠ€

μ΅œμ†Œμ£Όμ˜λ₯Ό λ”°λ₯΄λ©΄μ„œλ„ 좔상적인 μΈν„°νŽ˜μ΄μŠ€λ₯Ό 섀계할 수 μžˆλŠ” κ°€μž₯ 쒋은 방법은 μ±…μž„ 주도 섀계 방법을 λ”°λ₯΄λŠ” 것이닀. κ·ΈλŸ¬λ‚˜ μ±…μž„ 주도 섀계 방법이 ν›Œλ₯­ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 얻을 수 μžˆλŠ” 지침을 μ œκ³΅ν•œλ‹€κ³  ν•˜λ”λΌλ„ μ˜¬λ°”λ₯Έ 섀계에 λ„λ‹¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν›Œλ₯­ν•œ μΈν„°νŽ˜μ΄μŠ€κ°€ κ°€μ§€λŠ” 곡톡적인 νŠΉμ§•μ„ μ•Œμ•„μ•Ό ν•œλ‹€.

퍼블릭 μΈν„°νŽ˜μ΄μŠ€μ˜ ν’ˆμ§ˆμ— 영ν–₯을 λ―ΈμΉ˜λŠ” 원칙과 기법

  • λ””λ―Έν„° 법칙(Law of Demeter)
    • 였직 ν•˜λ‚˜μ˜ λ„νŠΈ(.)만 μ‚¬μš©ν•˜λΌ(use only one dot)
      • λ””λ―Έν„° 법칙을 λ”°λ₯΄κΈ° μœ„ν•΄μ„œλŠ” ν΄λž˜μŠ€κ°€ νŠΉμ •ν•œ 쑰건을 λ§Œμ‘±ν•˜λŠ” λŒ€μƒμ—κ²Œλ§Œ λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•˜λ„λ‘ ν”„λ‘œκ·Έλž˜λ°ν•΄μ•Ό ν•œλ‹€.
      • λ””λ―Έν„° 법칙은 μΊ‘μŠν™”λ₯Ό λ‹€λ₯Έ κ΄€μ μ—μ„œ ν‘œν˜„ν•œ 것이닀.
      • λ””λ―Έν„° 법칙을 μœ„λ°˜ν•˜λŠ” μ½”λ“œ: screening.getMovie().getDiscountConditions();
  • 묻지 말고 μ‹œμΌœλΌ(Tell, Don't Ask)
    • 객체의 μƒνƒœμ— λŒ€ν•΄ 묻지 말고 μ‹œμΌœλΌ. μƒνƒœ 기반으둜 결정을 내리면 후에 객체의 μƒνƒœλ₯Ό λ³€κ²½μ‹œν‚¨λ‹€λ©΄? μ–΄λ””μ„œ 값이 λ³€κ²½λœκ±΄μ§€ μ°ΎκΈ° μœ„ν•΄ 헀맬 κ°€λŠ₯성이 μžˆλ‹€. μƒνƒœλ₯Ό λ¬»λŠ” μ˜€νΌλ ˆμ΄μ…˜λ³΄λ‹€ 행동을 μš”μ²­ν•˜λŠ” μ˜€νΌλ ˆμ΄μ…˜μœΌλ‘œ λŒ€μ²΄ν•΄μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν–₯μƒμ‹œν‚€μž.
  • μ˜λ„λ₯Ό λ“œλŸ¬λ‚΄λŠ” μΈν„°νŽ˜μ΄μŠ€(Intention Revealing Interface)
    • κ΅¬ν˜„κ³Ό κ΄€λ ¨λœ λͺ¨λ“  정보λ₯Ό μΊ‘μŠν™”ν•˜κ³  객체의 퍼블릭 μΈν„°νŽ˜μ΄μŠ€μ—λŠ” ν˜‘λ ₯κ³Ό κ΄€λ ¨λœ μ˜λ„λ§Œμ„ ν‘œν˜„ν•΄μ•Ό ν•œλ‹€.

⭐️ μ›μΉ™μ˜ 함정

μ„€κ³„λŠ” νŠΈλ ˆμ΄λ“œμ˜€ν”„μ˜ 산물이닀. μ μš©ν•˜λ €λŠ” 원칙과 기법듀을 λͺ¨λ“  사둀에 μ–΅μ§€λ‘œ λΌμ›Œλ§žμΆ”λ €κ³  ν•œλ‹€λ©΄ λΆ€μ ν•©ν•œ μƒν™©μ—μ„œλ„ λ¬΄μ§ˆμ„œν•œ μ½”λ“œκ°€ 생성될 수 μžˆλ‹€. 원칙을 μ–΄λŠλΆ€λΆ„μ—μ„œ μ μš©ν•˜κ³  μ μš©ν•˜μ§€ μ•Šμ„κΉŒ, μ–΄λŠλΆ€λΆ„μ—μ„œ μ μš©ν•˜λ©΄ μœ μš©ν•˜κ²Œλ κΉŒλ₯Ό κ³ λ―Όν•˜μž.

λ””λ―Έν„°μ˜ 법칙쀑. ν•˜λ‚˜μ˜ λ„νŠΈλ§Œμ„ μ‚¬μš©ν•˜λΌλŠ” 것은 list.stream.filter.~~~ 와 같은 κ³³μ—μ„œλ„ μ μš©ν•˜λΌλŠ” 것이 μ•„λ‹ˆλ‹€.
이 λ©”μ„œλ“œ 체이닝은 λ™μΌν•œ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€. builderνŒ¨ν„΄μ˜ κ²½μš°μ—λ„ λ™μΌν•˜λ‹€.
이처럼 κΈ°μ°¨ 좩돌과 같은 μ½”λ“œμ—¬λ„ 외뢀에 정보λ₯Ό λ…ΈμΆœν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ λ””λ―Έν„° 법칙을 μ€€μˆ˜ν•œ 것이닀.

λ¬»μ§€μ•Šκ³  μ‹œμΌœλΌκ°€ 적용 될 κ²½μš°κ°€ μžˆλŠ”λ° 자료ꡬ쑰의 객체의 경우 λ‚΄λΆ€λ₯Ό λ…ΈμΆœν•΄μ•Όν•˜λŠ”λ°, 결ꡭ에 내뢀정보λ₯Ό Publicν•˜κ²Œ κ³΅μœ ν•΄μ•Όν•œλ‹€.
객체에 μ‹œν‚€λŠ” 것이 항상 κ°€λŠ₯ν•˜μ§€ μ•Šλ‹€. 가끔은 λ¬Όμ–΄λ³΄μ•„μ•Όν•œλ‹€.

⭐️ λͺ…λ Ή - 쿼리 원칙

ν•„μš”μ— 따라 λ¬Όμ–΄μ•Ό ν•œλ‹€λŠ” 사싀을 μ΄ν•΄ν•œλ‹€λ©΄ λͺ…λ Ή-쿼리 원칙을 μ•Œμ•„λ³΄μž.

μš©μ–΄

  • 루틴: μ–΄λ–€ 절차λ₯Ό λ¬Άμ–΄ 호좜 κ°€λŠ₯ν•˜λ„λ‘ 이름을 λΆ€μ—¬ν•œ κΈ°λŠ₯ λͺ¨λ“ˆ
  • ν”„λ‘œμ‹œμ €: μ •ν•΄μ§„ μ ˆμ°¨μ— 따라 λ‚΄λΆ€ μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” λ£¨ν‹΄μ˜ ν•œ μ’…λ₯˜
  • ν•¨μˆ˜: μ •ν•΄μ§„ μ ˆμ°¨μ— 따라 ν•„μš”ν•œ 값을 κ³„μ‚°ν•΄μ„œ λ°˜ν™˜ν•˜λŠ” λ£¨ν‹΄μ˜ ν•œ μ’…λ₯˜

λͺ…λ Ή - ν”„λ‘œμ‹œμ €μ™€ λ™μΌν•œ κ°œλ…μœΌλ‘œ 보고 쿼리 - ν•¨μˆ˜μ™€ λ™μΌν•œ κ°œλ…μœΌλ‘œ λ³Έλ‹€.


λͺ…λ Ήκ³Ό 쿼리λ₯Ό λΆ„λ¦¬ν•΄μ„œ μ–»λŠ” μž₯점이 λ¬΄μ—‡μΌκΉŒ??
κ°€μž₯ 큰 μž₯점은 μ½”λ“œκ°€ μ˜ˆμΈ‘ν•˜κΈ° μ‰¬μ›Œμ§„λ‹€λŠ” 것이닀.
κ°€λ Ή μ½”λ“œλ₯Ό 보면

public int findItemNo(Someclass someclass) {
  someClass.setItemNo(5);
  return someClass.getItemNo();
}

λΆ„λͺ… μ•„μ΄ν…œ 이름을 찾으라고 λ©”μ„œλ“œλ₯Ό λͺ…λͺ…해놓고 νŒŒλΌλ―Έν„°λ₯Ό λ°›λŠ” 객체의 μƒνƒœλ₯Ό λ³€κ²½ν•œ ν›„ 이 값을 λ¦¬ν„΄ν•œλ‹€.

κ·Έλ ‡λ‹€λ©΄ 이 someClass 아무도 λͺ¨λ₯΄κ²Œ μƒνƒœλ³€κ²½μ΄ λ˜μ–΄λ²„λ¦° 것이닀.

이처럼 λ©”μ„œλ“œλ₯Ό 톡해 μ˜ˆμΈ‘ν•  수 μ—†λŠ” κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€λ©΄ 버그가 λ°œμƒν•  μˆ˜λ„ 있고 λ””λ²„κΉ…ν•˜κΈ° μœ„ν•΄ λ©”μ„œλ“œλ“€μ„ μƒ…μƒ…νžˆ 찾아보아야 ν•œλ‹€.

뢄리λ₯Ό ν•˜μž

public void changeItemNo(SomeClass someClass, int itemNo) {
  someClass.itemNo = itemNo;
}
public int changeItemNo(SomeClass someClass) {
  return someclass.getItemNo();
}

λ¬Όλ‘  μœ„μ˜ μ½”λ“œλ“€μ€ λ‚΄λΆ€ κ΅¬ν˜„μ„ 톡해 getter와 setterλ°©μ‹μœΌλ‘œ μ§€ 수 μžˆκ² μ§€λ§Œ. μš”μ μ€ λ©”μ„œλ“œκ°€ κ΅¬ν˜„ν•˜λŠ” κΈ°λŠ₯에 λŒ€ν•΄μ„œ λͺ…λ Ή 쿼리둜 λΆ„λ¦¬ν•˜λŠ” 것이닀.

μ»΄ν“¨ν„°μ—μ„œ λͺ…령은 λΆ€μˆ˜νš¨κ³Ό(쀑간에 μƒνƒœκ°€ λ³€ν•˜λŠ”)λ₯Ό κ°€μ Έλ‹€ μ£ΌλŠ”λ°, 이 λΆ€μˆ˜νš¨κ³Όκ°€ μ•„μ˜ˆ μ‘΄μž¬ν•˜μ§€ μ•Šλ‹€λ©΄ λΆˆλ³€μ„±(μƒνƒœκ°€ λ³€ν•˜μ§€ μ•ŠμŒ)을 μ‘±ν•˜λ©° μ°Έμ‘° 투λͺ…μ„± 즉, ν•΄λ‹Ή κΈ°λŠ₯에 어디에 μž…λ ₯λ˜μ–΄λ„ 같은 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” κ²°κ³Όλ₯Ό μ£Όκ²Œλœλ‹€.

객체지ν–₯은 μƒνƒœλ³€κ²½μ΄λΌλŠ” λΆ€μˆ˜νš¨κ³Όλ₯Ό 기반으둜 μƒκ°ν•˜κΈ° λ•Œλ¬Έμ— 참쑰투λͺ…성은 μ˜ˆμ™Έμ— 가깝닀.

κ·ΈλŸ¬λ‚˜, λͺ…λ Ή-쿼리 μ›μΉ™μœΌλ‘œ 이 간극을 μ΅œλŒ€ν•œ 쀄일 수 μžˆλ‹€.


좜처
였브젝트 - μ½”λ“œλ‘œ μ΄ν•΄ν•˜λŠ” 객체지ν–₯ 섀계
https://github.com/eternity-oop/object

0개의 λŒ“κΈ€