[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item20. μΆ”μƒν΄λž˜μŠ€λ³΄λ‹€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μš°μ„ ν•˜λΌ.

2023. 3. 3. 13:48ㆍJAVA/Effective JAVA

728x90

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item20. μΆ”μƒν΄λž˜μŠ€λ³΄λ‹€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μš°μ„ ν•˜λΌ. 

μžλ°”κ°€ μ œκ³΅ν•˜λŠ” 닀쀑 κ΅¬ν˜„ λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œλŠ” μΆ”μƒν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€ μ΄λ ‡κ²Œ 두가지가 μžˆλ‹€. 

μžλ°” 8λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€λ„ λ””ν΄νŠΈ λ©”μ„œλ“œ default method λ₯Ό μ œκ³΅ν•  수 있게 λ˜λ©΄μ„œ μ΄μ œλŠ” 두 λ©”μ»€λ‹ˆμ¦˜ λͺ¨λ‘ μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ ν˜•νƒœλ‘œ μ œκ³΅ν•  수 μžˆλ‹€. 

 

μΆ”μƒν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€μ˜ 큰 μ°¨μ΄μ μœΌλ‘œλŠ” μΆ”μƒν΄λž˜μŠ€κ°€ μ •μ˜ν•œ νƒ€μž…μ„ κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€λŠ” λ°˜λ“œμ‹œ μΆ”μƒν΄λž˜μŠ€μ˜ ν•˜μœ„ ν΄λž˜μŠ€κ°€ λ˜μ–΄μ•Ό ν•œλ‹€λŠ” 점이닀. μžλ°”λŠ” 단일 μƒμ†λ§Œ μ§€μ›ν•˜κΈ° λ•Œλ¬Έμ— 좔상 클래슀 방식은 μƒˆλ‘œμš΄ νƒ€μž…μ„ μ •μ˜ν•˜λŠ”λ° μ»€λ‹€λž€ μ œμ•½μ„ μ–»κ²Œ λœλ‹€. 

반면 μΈν„°νŽ˜μ΄μŠ€κ°€ μ„ μ–Έν•œ λ©”μ„œλ“œλ₯Ό λͺ¨λ‘ μ •μ˜ν•˜κ³  κ·Έ 일반 κ·œμ•½μ„ 잘 지킨 클래슀라면 λ‹€λ₯Έ μ–΄λ–€ 클래슀λ₯Ό μƒμ†ν–ˆλ“  같은 νƒ€μž…μœΌλ‘œ μ·¨κΈ‰λœλ‹€. 

 

 

 

μΈν„°νŽ˜μ΄μŠ€ μž₯점 

1️⃣ μžλ°” 8λΆ€ν„°λŠ” μΈν„°νŽ˜μ΄μŠ€μ—μ„œλ„ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•  수 μžˆλ‹€. 

public interface TimeClient
{
   void setTime(int hour, int minute, int second);
   
   void setDate(int day, int month, int year);
   
   void setDateAndTime(int day, int month, int year, int hour, int minute, int second);
   
   LocalDateTime getLocalDateTime();
   
   static ZoneId getZoneId(String zoneString)
   {
      try
      {
         return ZoneId.of(zoneString);
      }
      catch (DateTimeException e) {
         System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead");
         return ZoneId.systemDefault();
      }
   }
   
   // μžλ°” 8λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€λ„ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•  수 μžˆλ‹€.
   default ZonedDateTime getZoneDateTime(String zoneString)
   {
      return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
   }
   
}

 

public class SimpleTimeClient implements TimeClient
{
   private LocalDateTime localDateTime;
   
   public SimpleTimeClient()
   {
      localDateTime = LocalDateTime.now();
   }
   
   @Override
   public void setTime(int hour, int minute, int second)
   {
      LocalDate currentDate = LocalDate.from(localDateTime);
      LocalTime timeToSet = LocalTime.of(hour, minute, second);
      localDateTime = LocalDateTime.of(currentDate, timeToSet);
   }
   
   @Override
   public void setDate(int day, int month, int year)
   {
      LocalDate dateToSet = LocalDate.of(day, month, year);
      LocalTime currentTime = LocalTime.from(localDateTime);
      localDateTime = LocalDateTime.of(dateToSet, currentTime);
   }
   
   @Override
   public void setDateAndTime(int day, int month, int year, int hour,
         int minute, int second)
   {
      LocalDate dateToSet = LocalDate.of(day, month, year);
      LocalTime timeToSet = LocalTime.of(hour, minute, second);
      localDateTime = LocalDateTime.of(dateToSet, timeToSet);
   }
   
   @Override
   public LocalDateTime getLocalDateTime()
   {
      return localDateTime;
   }
   
   public String toString()
   {
      return localDateTime.toString();
   }
   
   public static void main(String[] args)
   {
      TimeClient myTimeClient = new SimpleTimeClient();
      System.out.println("myTimeClient = " + myTimeClient);
      System.out.println(
            "myTimeClient.getZoneDateTime = " + myTimeClient.getZoneDateTime("America/Los_Angeles"));
   }
}

 

 

2️⃣ κΈ°μ‘΄ ν΄λž˜μŠ€μ—λ„ μ†μ‰½κ²Œ μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄λ„£μ„ 수 μžˆλ‹€. 

μΈν„°νŽ˜μ΄μŠ€κ°€ μš”κ΅¬ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 아직 μ—†λ‹€λ©΄ μΆ”κ°€ν•˜κ³  클래슀 선언에 implements ꡬ문만 μΆ”κ°€ν•΄μ£Όλ©΄ λœλ‹€! 

 

3️⃣ μΈν„°νŽ˜μ΄μŠ€λŠ” 믹슀인 mixin μ •μ˜μ— μ•ˆμ„±λ§žμΆ€μ΄λ‹€. (선택적인 κΈ°λŠ₯ μΆ”κ°€) 

λ―ΉμŠ€μΈμ΄λž€ ν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•  수 μžˆλŠ” νƒ€μž…μœΌλ‘œ, λ―ΉμŠ€μΈμ„ κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ— μ›λž˜μ˜ '주된 νƒ€μž…' 외에도 νŠΉμ • 선택적 ν–‰μœ„λ₯Ό μ œκ³΅ν•œλ‹€κ³  μ„ μ–Έν•˜λŠ” 효과λ₯Ό μ€€λ‹€. 

ex) Comparable은 μžμ‹ μ„ κ΅¬ν˜„ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€λ“€λΌλ¦¬λŠ” μˆœμ„œλ₯Ό μ •ν•  수 μžˆλ‹€κ³  μ„ μ–Έν•˜λŠ” 믹슀인 μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€. 

이처럼 λŒ€μƒ νƒ€μž…μ˜ 주된 κΈ°λŠ₯에 선택적 κΈ°λŠ₯을 ν˜Όν•©(mixed in) ν•œλ‹€κ³  ν•΄μ„œ 믹슀인이라고 λΆ€λ₯Έλ‹€. 

 

μΆ”μƒν΄λž˜μŠ€λ‘œλŠ” λ―ΉμŠ€μΈμ„ μ •μ˜ν•  수 μ—†λŠ”λ° μ™œλƒν•˜λ©΄ κΈ°μ‘΄ ν΄λž˜μŠ€μ— λ§μ”ŒμšΈ 수 μ—†κΈ° λ•Œλ¬Έμ΄λ©°, ν΄λž˜μŠ€λŠ” λ‘κ°œ μ΄μƒμ˜ 클래슀λ₯Ό 상속받을 수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. 

 

 

4️⃣ μΈν„°νŽ˜μ΄μŠ€λ‘œλŠ” 계측ꡬ쑰가 μ—†λŠ” νƒ€μž… ν”„λ ˆμž„μ›Œν¬λ₯Ό λ§Œλ“€ 수 μžˆλ‹€. 

νƒ€μž…μ„ κ³„μΈ΅μ μœΌλ‘œ 잘 μ •μ˜ν•˜λ©΄ μˆ˜λ§Žμ€ κ°œλ…μ„ ꡬ쑰적으둜 잘 ν‘œν˜„ν•  수 μžˆμ§€λ§Œ, ν˜„μ‹€μ—μ„œλŠ” 계측을 μ—„κ²©νžˆ κ΅¬λΆ„ν•˜κΈ° μ–΄λ €μš΄ κ°œλ…λ„ μžˆλ‹€. 

책에 λ‚˜μ˜¨ μ˜ˆλ‘œλŠ” κ°€μˆ˜(Singer) μΈν„°νŽ˜μ΄μŠ€μ™€ μž‘κ³‘κ°€(SongWriter) μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλ‹€κ³  ν•˜λ©΄..

public interface Singer
{
   AudioClip sing(Song song);
}
public interface SongWriter
{
   Song compose(int shartPosition);
}

근데 μ£Όλ³€μ—λŠ” μž‘κ³‘λ„ 같이 ν•˜λŠ” κ°€μˆ˜λ“€λ„ λ§Žλ‹€. 

public interface SingerSongwriter extends Singer, SongWriter
{
   AudioClip strum();
   
   void actSensitive();
   
}

μ΄λ ‡κ²Œ νƒ€μž…μ„ μΈν„°νŽ˜μ΄μŠ€λ‘œ μ •μ˜ν•˜λ©΄ κ°€μˆ˜ ν΄λž˜μŠ€κ°€ singer와 songWriterλ₯Ό λͺ¨λ‘ κ΅¬ν˜„ν•΄λ„ μ „ν˜€ λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ”λ‹€.

심지어 Singer와 Songwriterλ₯Ό λͺ¨λ‘ ν™•μž₯ν•˜κ³  μƒˆλ‘œμš΄ λ©”μ„œλ“œκΉŒμ§€ μΆ”κ°€ν•΄ 제 3의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•  μˆ˜λ„ μžˆλ‹€. 

 

 

5️⃣ 래퍼 클래슀 κ΄€μš©κ΅¬μ™€ ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ μΈν„°νŽ˜μ΄μŠ€λŠ” κΈ°λŠ₯을 ν–₯μƒμ‹œν‚€λŠ” μ•ˆμ „ν•˜κ³  κ°•λ ₯ν•œ μˆ˜λ‹¨μ΄ λœλ‹€. 

νƒ€μž…μ„ 좔상 클래슀둜 μ •μ˜ν•΄λ‘λ©΄ νƒ€μž…μ— κΈ°λŠ₯을 μΆ”κ°€ν•˜λŠ” 방법은 μƒμ†λΏμ΄μ§€λ§Œ μƒμ†ν•΄μ„œ λ§Œλ“  ν΄λž˜μŠ€λŠ” 래퍼 ν΄λž˜μŠ€λ³΄λ‹€ ν™œμš©λ„κ°€ 떨어지고 깨지기 쉽닀.

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item18. μƒμ†λ³΄λ‹€λŠ” μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λΌ. (tistory.com)

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item18. μƒμ†λ³΄λ‹€λŠ” μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λΌ.

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item18. μƒμ†λ³΄λ‹€λŠ” μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λΌ. 상속을 μ‚¬μš©ν•˜λ©΄ μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, 잘λͺ» μƒμ†ν•˜λ©΄ 였λ₯˜κ°€ λ°œμƒν•  수 μžˆλ‹€. μƒμœ„ ν΄λž˜μŠ€μ™€ ν•˜μœ„ ν΄λž˜μŠ€κ°€ λͺ¨λ‘ 같은 ν”„λ‘œκ·Έλž˜

hyejin.tistory.com

 

 

 

6️⃣ μΈν„°νŽ˜μ΄μŠ€ λ©”μ„œλ“œ 쀑 κ΅¬ν˜„μ΄ λͺ…λ°±ν•œ 것이 μžˆλ‹€λ©΄ λ””ν΄λ“œ λ©”μ„œλ“œλ‘œ μ œκ³΅ν•΄μ„œ ν”„λ‘œκ·Έλž˜λ¨Έμ˜ 일감을 λœμ–΄μ€„ 수 μžˆλ‹€. 

λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•  λ•Œμ—λŠ” μƒμ†ν•˜λ €λŠ” μ‚¬λžŒμ„ μœ„ν•΄ @implSpec μžλ°”λ… νƒœκ·Έλ₯Ό λΆ™μ—¬ λ¬Έμ„œν™”ν•΄μ•Ό ν•œλ‹€. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90