본문으둜 κ±΄λ„ˆλ›°κΈ°

🌈 Chapter 2: 객체λ₯Ό ν™œμš©ν•œ ν…ŒμŠ€νŠΈ 주도 개발

πŸ“š 객체 망​

  • 객체 지ν–₯ μ„€κ³„λŠ” 객체 μžμ²΄λ³΄λ‹€ 객체 κ°„μ˜ μ˜μ‚¬μ†Œν†΅μ— 더 μ§‘μ€‘ν•œλ‹€.
  • κ°μ²΄λŠ” λ©”μ‹œμ§€λ‘œ μ˜μ‚¬μ†Œν†΅ν•œλ‹€. 즉, κ°μ²΄λŠ” λ‹€λ₯Έ 객체와 λ©”μ‹œμ§€λ₯Ό μ£Όκ³ λ°›μœΌλ©΄μ„œ λ°˜μ‘ν•œλ‹€.
  • κ°μ²΄μ—λŠ” μžμ‹ μ΄ 이해할 수 μžˆλŠ” λͺ¨λ“  μœ ν˜•μ˜ λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•˜λŠ” λ©”μ„œλ“œκ°€ 있으며, λŒ€λΆ€λΆ„ λ‹€λ₯Έ 객체와 μ˜μ‚¬μ†Œν†΅μ„ μ‘°μœ¨ν•˜λŠ” 데 μ‚¬μš©ν•˜λŠ” λ‚΄λΆ€ μƒνƒœλ₯Ό μΊ‘μŠν™”ν•œλ‹€.
  • 객체 ꡬ성을 관리할 λͺ©μ μœΌλ‘œ μž‘μ„±ν•˜λŠ” μ½”λ“œλ₯Ό 객체망의 ν–‰μœ„μ— λŒ€ν•œ 선언적(declarative) μ •μ˜λΌ ν•œλ‹€. μ‹œμŠ€ν…œμ„ 이런 μ‹μœΌλ‘œ κ΅¬μΆ•ν•˜λ©΄ 방법이 μ•„λ‹ˆλΌ λͺ©μ μ— 집쀑할 수 μžˆμ–΄ μ‹œμŠ€ν…œμ˜ ν–‰μœ„λ₯Ό λ³€κ²½ν•˜κΈ°κ°€ 쉽닀.

πŸ“š κ°’κ³Ό 객체​

  • μ‹œμŠ€ν…œμ„ 섀계할 λ•ŒλŠ” κ°’κ³Ό 객체λ₯Ό κ΅¬λΆ€λ‚˜λŠ” 것이 μ€‘μš”ν•˜λ‹€. 값은 λ³€ν•˜μ§€ μ•ŠλŠ” μ–‘μ΄λ‚˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λ©°, κ°μ²΄λŠ” μ‹œκ°„μ΄ 지남에 따라 μƒνƒœκ°€ 변할지도 λͺ¨λ₯΄μ§€λ§Œ μ‹λ³„μžκ°€ μžˆλŠ” 계산 절차λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
  • 값은 양이 κ³ μ •λœ λΆˆλ³€ μΈμŠ€ν„΄μŠ€λ‹€. 값은 κ°œλ³„μ μΈ μ‹λ³„μžκ°€ μ—†μœΌλ―€λ‘œ 두 κ°’ μΈμŠ€ν„΄μŠ€μ˜ μƒνƒœκ°€ κ°™λ‹€λ©΄ 사싀상 λ™μΌν•œ μ…ˆμ΄λ‹€. λ”°λΌμ„œ 두 κ°’μ˜ μ‹λ³„μžλ₯Ό λΉ„κ΅ν•˜λŠ” 것은 μ μ ˆν•˜μ§€ μ•Šλ‹€.
  • κ°μ²΄λŠ” λ³€κ²½ κ°€λŠ₯ν•œ μƒνƒœλ₯Ό μ΄μš©ν•΄ μ‹œκ°„μ˜ 좔이에 λ”°λ₯Έ 객체의 ν–‰μœ„λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. νƒ€μž…μ΄ λ˜‘κ°™μ€ 두 κ°μ²΄λŠ” ν˜„μž¬ μƒνƒœκ°€ μ •ν™•νžˆ λ™μΌν•˜λ”λΌλ„ λ³„κ°œμ˜ μ‹λ³„μžλ₯Ό μ§€λ‹Œλ‹€. μ΄λŠ” 두 객체가 ν–₯ν›„ μ–΄λ–€ λ©”μ‹œμ§€λ₯Ό μ „λ‹¬λ°›λŠλƒμ— 따라 μƒνƒœκ°€ λ‹¬λΌμ§ˆ 수 있기 λ•Œλ¬Έμ΄λ‹€.

πŸ“š λ©”μ‹œμ§€λ₯Ό λ”°λ₯΄λΌβ€‹

  • λ‹€λ₯Έ 객체와 μ‰½κ²Œ 관계λ₯Ό 맺을 수 있게 객체λ₯Ό μ„€κ³„ν•˜κΈ°λ§Œ ν•œλ‹€λ©΄ κ³ μˆ˜μ€€μ˜ 선언적 접근법이 μ£ΌλŠ” ν˜œνƒμ„ λˆ„λ¦΄ 수 μžˆλ‹€.
  • μ˜μ‚¬μ†Œν†΅ νŒ¨ν„΄μ€ 객체듀이 λ‹€λ₯Έ 객체와 μƒν˜Έ μž‘μš©ν•˜λŠ” 방법을 κ³Όμž₯ν•˜λŠ” 각쒅 κ·œμΉ™μœΌλ‘œ ꡬ성돼 μžˆλ‹€. μžλ°” 같은 μ–Έμ–΄μ—μ„œλŠ” 클래슀 λŒ€μ‹  μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄ 객체의 역할을 νŒŒμ•…ν•œλ‹€.
  • κ°μ²΄λŠ” 역할을 ν•˜λ‚˜ 이상 κ΅¬ν˜„ν•œ 것이며, 역할은 κ΄€λ ¨λœ μ±…μž„μ˜ 집합이며, μ±…μž„μ€ μ–΄λ–€ 과업을 μˆ˜ν–‰ν•˜κ±°λ‚˜ 정보λ₯Ό μ•Œμ•„μ•Όν•  의무λ₯Ό λ§ν•œλ‹€. ν˜‘λ ₯은 κ°μ²΄λ‚˜ μ—­ν• μ˜ μƒν˜Έ μž‘μš©μ— ν•΄λ‹Ήν•œλ‹€.

πŸ“š 묻지 말고 λ§ν•˜λΌβ€‹

  • 객체λ₯Ό ν˜ΈμΆœν•  땐 이웃 객체가 ν•˜λŠ” μ—­ν•  μΈ‘λ©΄μ—μ„œ ν•΄λ‹Ή 객체가 무엇을 μ›ν•˜λŠ”μ§€ κΈ°μˆ ν•˜κ³ , 호좜된 객체가 κ·ΈλŸ¬ν•œ λ°”λ₯Ό μ–΄λ–»κ²Œ μ‹€ν˜„ν• μ§€ κ²°μ •ν•˜κ²Œ ν•΄μ•Ό ν•œλ‹€. 이것은 ν”νžˆ 묻지 말고 λ§ν•˜λΌ μŠ€νƒ€μΌμ΄λ‚˜ λ””λ―Έν„°μ˜ λ²•μΉ™μœΌλ‘œ μ•Œλ €μ Έ μžˆλ‹€. κ°μ²΄λŠ” 그것이 λ‚΄λΆ€μ μœΌλ‘œ λ³΄μœ ν•˜κ³  μžˆκ±°λ‚˜ λ©”μ‹œμ§€λ₯Ό 톡해 ν™•λ³΄ν•œ μ •λ³΄λ§Œ 가지고 μ˜μ‚¬ 결정을 λ‚΄λ €μ•Ό ν•œλ‹€. κ°μ²΄λŠ” λ‹€λ₯Έ 객체λ₯Ό 탐색해 λ­”κ°€λ₯Ό μΌμ–΄λ‚˜κ²Œ ν•΄μ„œλŠ” μ•ˆ λœλ‹€.
  • 이 μŠ€νƒ€μΌμ„ λ”°λ₯΄μ§€ μ•ŠμœΌλ©΄ μ—΄μ°¨ 전볡(κΈ°μ°¨ 좩돌, train wreck) μ½”λ“œλΌκ³  μ•Œλ €μ§„ μ½”λ“œκ°€ λ§Œλ“€μ–΄μ§„λ‹€.
// κΈ°μ°¨ 좩돌 μ½”λ“œ 예
((EditSaveCustomizer) master.getModelisable()
.getDockablePanel()
.getCustomizer())
.getSaveItem().setEnabled(Boolean.FALSE.booleanValue());
  • μ›λž˜ γ…—λ“œκ°€ λ‹€μŒκ³Ό 같은 μ½”λ“œλ₯Ό μ˜λ―Έν•œλ‹€λŠ” 사싀을 κΉ¨λ‹¬μ•˜λ‹€.
master.allowSavingOfCustomisations();
  • μ΄λ ‡κ²Œ ν•˜λ©΄ λͺ¨λ“  κ΅¬ν˜„ μ„ΈλΆ€ 사항이 λ©”μ„œλ“œ 호좜 ν•œ 번으둜 쀄어든닀. masterλ₯Ό μ΄μš©ν•˜λŠ” μͺ½μ—μ„œλŠ” λ©”μ„œλ“œλ₯Ό 연이어 ν˜ΈμΆœν•  λ•Œ λ°˜ν™˜λ˜λŠ” 객체의 νƒ€μž…μ— κ΄€ν•΄ λ”λŠ” μ•Œ ν•„μš”κ°€ μ—†λ‹€. μ•„μšΈλŸ¬ 섀계 변경이 μ½”λ“œ 기반의 ꡬ석ꡬ석 영ν–₯을 λΌμΉ˜λŠ” μœ„ν—˜λ„ μ€„μ—ˆλ‹€.
  • 이 원칙 덕뢄에 μ ‘κ·Όμž λ©”μ„œλ“ 연이어 ν˜ΈμΆœλ˜λ„λ‘ μ•”μ‹œμ μœΌλ‘œ λ‘κΈ°λ³΄λ‹€λŠ” 객체 κ°„μ˜ μƒν˜Έ μž‘μš©μ„ λͺ…μ‹œμ μœΌλ‘œ λ§Œλ“€κ³  거기에 이름을 λΆ€μ—¬ν•˜κ²Œ λœλ‹€.
  • 짧은 ν˜•νƒœλŠ” λ‹¨μˆœνžˆ κ΅¬ν˜„ 방식이 μ•„λ‹Œ μ½”λ“œμ˜ λͺ©μ μœΌλ‘œ 훨씬 더 λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚Έλ‹€.

πŸ“š κ·Έλž˜λ„ 가끔은 물어라​

  • κ°’κ³Ό μ»¬λ ‰μ…˜μœΌλ‘œλΆ€ν„° 정보λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜ νŒ©ν„°λ¦¬λ₯Ό μ΄μš©ν•΄ μƒˆ 객체λ₯Ό 생성할 λ•ŒλŠ” λ¬»λŠ”λ‹€.
  • 예λ₯Ό λ“€μ–΄ 전체 μ’Œμ„μ„ λŒ€μƒμœΌλ‘œ μ˜ˆμ•½μ„μ„ κ³ λ₯΄κ²Œ λ°°λΆ„ν•˜κ³ λ§Œ μ‹Άλ‹€λ©΄ λ‹€μŒκ³Ό 같은 μ½”λ“œλ‘œ μ‹œμž‘ν• μ§€λ„ λͺ¨λ₯Έλ‹€.
public class Train {
private final List<Carriage> carriages [...]
private int percentReservedBarrier = 70;

public void reserveSeats(ReservationRequest request) {
for(Carriage carriage: carriages) {
if (carriage.getSeats().getPercentReserved() < percentReservedBarrier) {
request.reserveSeatsIn(carriage);
return;
}

request.cannotFindSeats();
}
}
}
  • μ—¬κΈ°μ„œ Carriage의 λ‚΄λΆ€ ꡬ쑰λ₯Ό λ…ΈμΆœν•΄μ„œλŠ” μ•ˆ λ˜λŠ”λ°, μ΄λŠ” κΈ°μ°¨ μ•ˆμ— λ‹€μ–‘ν•œ μœ ν˜•μ˜ 객차가 있기 λ•Œλ¬Έλ§Œμ€ μ•„λ‹Œλ°, λŒ€μ‹  슀슀둜 닡을 κ°€λŠ ν•˜λŠ” 데 도움이 λ˜λŠ” 정보λ₯Ό λ¬»κΈ°λ³΄λ‹€λŠ” 진정 λ‹΅ν•˜κ³ μž ν•˜λŠ” μ§ˆλ¬Έμ„ λ˜μ Έμ•Ό ν•œλ‹€.
public void reserveSeats(ReservationRequest request) {
for(Carriage carriage: carriages) {
if(carriage.hasSeatsAvailableWithin(percentReservedBarrier)) {
request.reserveSeatsIn(carriage);
return;
}
}

request.cannotFindSeats();
}
  • 질의 λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λ©΄ κ°€μž₯ μ μ ˆν•œ 객체에 ν–‰μœ„κ°€ 자리 μž‘μ•„ ν–‰μœ„μ— μ΄ν•΄ν•˜κΈ° μ‰¬μš΄ 이름이 생기고 ν…ŒμŠ€νŠΈν•˜κΈ°κ°€ μ‰¬μ›Œμ§„λ‹€.

πŸ“š ν˜‘λ ₯ 객체의 λ‹¨μœ„ ν…ŒμŠ€νŠΈβ€‹

  • μ–΄λ–»κ²Œ 객체의 λ‚΄λΆ€ μƒνƒœλ₯Ό λ“œλŸ¬λ‚΄μ§€ μ•Šκ³  객체λ₯Ό ν˜ΈμΆœν•  λ•Œ 이웃 객체에 λ©”μ‹œμ§€λ₯Ό 보낼 수 μžˆμ„κΉŒ?
    • ν•œ 가지 방법은 ν…ŒμŠ€νŠΈμ— μ‘΄μž¬ν•˜λŠ” λŒ€μƒ 객체의 이웃을 λ‹€λ₯Έ λŒ€μ²΄λ¬Ό, 즉 λͺ© 객체(mock object)둜 λŒ€μ²΄ν•˜λŠ” 것이닀. κ·Έλ ‡κ²Œ ν•˜λ©΄ λ°œμƒν•˜λŠ” μ΄λ²€νŠΈμ— λŒ€ν•΄ λŒ€μƒ 객체가 κ°€μ§œ 이웃과 μ–΄λ–»κ²Œ μƒν˜Έ μž‘μš©ν• μ§€ 지정할 수 μžˆλ‹€. 이 같은 λͺ…μ„Έλ₯Ό μ˜ˆμƒ ꡬ문이라 ν•œλ‹€. ν…ŒμŠ€νŠΈκ°€ μ§„ν–‰λ˜λŠ” λ™μ•ˆ λͺ© κ°μ²΄λŠ” μžμ‹œλ‹ μ˜ˆμƒλŒ€λ‘œ ν˜ΈμΆœλλŠ”μ§€ λ‹¨μ •ν•œλ‹€.
  • ν…ŒμŠ€νŠΈλ₯Ό μ΄μš©ν•˜λ©΄ 객체에 ν•„μš”ν•œ 보쑰 역할을 νŒŒμ•…ν•˜λŠ” 데 도움이 되며, μ΄λŸ¬ν•œ 보쑰 역할은 μžλ°” μΈν„°νŽ˜μ΄μŠ€λ‘œ μ •μ˜λΌ 있고 μ‹œμŠ€ν…œμ˜ λ‚˜λ¨Έμ§€ 뢀뢄을 κ°œλ°œν•  λ•Œ μ‹€μ œ κ΅¬ν˜„μ²˜λŸΌ λ™μž‘ν•œλ‹€. 이λ₯Ό μš°λ¦¬λŠ” μΈν„°νŽ˜μ΄μŠ€ 발견이라고 ν•œλ‹€.

πŸ“š λͺ© 객체λ₯Ό ν™œμš©ν•œ TDD 지원​

  • 이 같은 μœ ν˜•μ˜ ν…ŒμŠ€νŠΈ 주도 ν”„λ‘œκ·Έλž˜λ°μ„ μ§€μ›ν•˜λ €λ©΄ μ΄μ›ƒν•˜λŠ” 객체의 λͺ© μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , ν•΄λ‹Ή λͺ© μΈμŠ€ν„΄μŠ€λ₯Ό μ–΄λ–»κ²Œ ν˜ΈμΆœν•˜κ³  μƒνƒœλ₯Ό κ²€μ‚¬ν•˜λŠ”κ°€μ— κ΄€ν•œ μ˜ˆμƒ ꡬ문을 μ •μ˜ν•œ λ‹€μŒ, ν…ŒμŠ€νŠΈλ₯Ό ν•  λ•Œ μŠ€ν… ν˜•νƒœλ‘œ λ™μž‘ν•  ν•„μš”κ°€ μžˆλŠ” ν–‰μœ„λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.
  • ν…ŒμŠ€νŠΈμ˜ 핡심 κ΅¬μ‘°λŠ” λ‹€μŒκ³Ό κ°™λ‹€.
    • ν•„μš”ν•œ λͺ© 객체 생성
    • λŒ€μƒ 객체λ₯Ό ν¬ν•¨ν•œ μ‹€μ œ 객체 생성
    • λŒ€μƒ κ°μ²΄μ—μ„œ λͺ© 객체가 μ–΄λ–»κ²Œ ν˜ΈμΆœλ μ§€ μ˜ˆμƒν•˜λŠ” λ°”λ₯Ό 기술
    • λŒ€μƒ κ°μ²΄μ—μ„œ 유발 λ©”μ„œλ“œλ₯Ό 호좜
    • κ²°κ³Ό 값이 μœ νš¨ν•˜κ³  μ˜ˆμƒλ˜λŠ” λ©”μ„œλ“œ 호좜이 λͺ¨λ‘ μΌμ–΄λ‚¬λŠ”μ§€ 확인
  • λ‹¨μœ„ ν…ŒμŠ€νŠΈλŠ” 그곳에 μžˆλŠ” λͺ¨λ“  객체λ₯Ό μƒμ„±ν•˜κ³  λŒ€μƒ 객체와 ν•΄λ‹Ή 객체의 ν˜‘λ ₯자 μ‚¬μ΄μ˜ μƒν˜Έ μž‘μš©μ— κ΄€ν•œ 단정을 λ§Œλ“€μ–΄ λ‚Έλ‹€.
  • λͺ¨λ“  ν…ŒμŠ€νŠΈ μ˜λ„λ₯Ό λͺ…ν™•ν•˜κ²Œ ν•΄μ„œ ν…ŒμŠ€νŠΈλ₯Ό 거친 κΈ°λŠ₯κ³Ό 보쑰 역할을 λ‹΄λ‹Ήν•˜λŠ” 기반 ꡬ쑰, 객체 ꡬ쑰λ₯Ό μ„œλ‘œ ꡬ뢄해야 ν•œλ‹€.