[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™” ν•˜λΌ. (λΆˆλ³€ 클래슀의 μž₯점과 단점)

2023. 2. 27. 17:05ㆍJAVA/Effective JAVA

728x90

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™”ν•˜λΌ. 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™” ν•˜λΌ. (λΆˆλ³€ 클래슀) (tistory.com)

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™” ν•˜λΌ. (λΆˆλ³€ 클래슀)

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item17. λ³€κ²½ κ°€λŠ₯성을 μ΅œμ†Œν™”ν•˜λΌ. λΆˆλ³€ ν΄λž˜μŠ€λž€? : κ°„λ‹¨νžˆ λ§ν•΄μ„œ κ·Έ μΈμŠ€ν„΄μŠ€μ˜ λ‚΄λΆ€ 값을 λ³€κ²½ν•  수 μ—†λŠ” 클래슀λ₯Ό λ§ν•œλ‹€. λΆˆλ³€ μΈμŠ€ν„΄μŠ€μ— κ°„μ§λœ μ •λ³΄λŠ” κ³ μ •λ˜μ–΄μ„œ 객체

hyejin.tistory.com

μ €λ²ˆ κΈ€μ—μ„œ λΆˆλ³€ ν΄λž˜μŠ€κ°€ 무엇인지 κ°œλ…κ³Ό λΆˆλ³€ 클래슀λ₯Ό λ§Œλ“œλŠ” 닀섯가지 κ·œμΉ™μ— λŒ€ν•΄μ„œ κ³΅λΆ€ν–ˆλ‹€.

λΆˆλ³€ ν΄λž˜μŠ€λŠ” κ°€λ³€ ν΄λž˜μŠ€λ³΄λ‹€ μ„€κ³„ν•˜κ³ , κ΅¬ν˜„ν•˜κ³  μ‚¬μš©ν•˜κΈ° μ‰¬μš°λ©°, 였λ₯˜κ°€ 생길 여지도 적고 훨씬 μ•ˆμ „ν•˜λ‹€κ³  ν–ˆλŠ”λ° 

μ’€ 더 μžμ„Έν•˜κ²Œ λΆˆλ³€ 클래슀의 μž₯점과 단점에 λŒ€ν•΄ 이번 κΈ€μ—μ„œ 곡뢀할 것이닀. 

 

 

λΆˆλ³€ 클래슀의 μž₯점 

public final class Complex
{
   private final double re;
   private final double im;
   
   public static final Complex ZERO = new Complex(0, 0);
   
   public static final Complex ONE = new Complex(1, 0);
   
   public static final Complex I = new Complex(0, 1);
   
   public Complex(double re, double im)
   {
      this.re = re;
      this.im = im;
   }
   
   public double realPart()
   {
      return re;
   }
   
   public double imaginaryPart()
   {
      return im;
   }
   
   public Complex plus(Complex complex)
   {
      return new Complex(re + complex.re , im + complex.im);
   }
   
   public static Complex valueOf(double re, double im)
   {
      return new Complex(re, im);
   }
   
   public Complex minus(Complex complex)
   {
      return new Complex(re - complex.re, im - complex.im);
   }
   
   public Complex times(Complex complex)
   {
      return new Complex(re * complex.re - im * complex.im , re * complex.im + im * complex.re);
   }
   
   public Complex divideBy(Complex complex)
   {
      double tmp = complex.re * complex.re + complex.im * complex.im;
      return new Complex((re * complex.re + im * complex.im) / tmp, (im * complex.re - re * complex.im) / tmp);
   }
   
   @Override
   public boolean equals(Object o)
   {
      if (this == o)
         return true;
      if (o == null || getClass() != o.getClass())
         return false;
      Complex complex = (Complex) o;
      return Double.compare(complex.re,
                       re) == 0 && Double.compare(
            complex.im, im) == 0;
   }
   
   @Override
   public int hashCode()
   {
      return Objects.hash(re, im);
   }
   
   @Override
   public String toString()
   {
      return "Complex{" +
            "re=" + re +
            ", im=" + im +
            '}';
   }
}

Complex ν΄λž˜μŠ€λŠ” λ³΅μ†Œμˆ˜(μ‹€μˆ˜λΆ€μ™€ ν—ˆμˆ˜λΆ€λ‘œ κ΅¬μ„±λœ 수)λ₯Ό ν‘œν˜„ν•˜λŠ” ν΄λž˜μŠ€μ΄λ‹€. 

realPartλŠ” μ‹€μˆ˜λΆ€μ˜ 값을 λ°˜ν™˜ν•˜λŠ” μ ‘κ·Όμž λ©”μ„œλ“œμ΄κ³ , imaginaryPartλŠ” ν—ˆμˆ˜λΆ€μ˜ 값을 λ°˜ν™˜ν•˜λŠ” μ ‘κ·Όμž λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€. 

그리고 사칙연산 λ©”μ„œλ“œ(plus, minus, times, dividedBy) λ₯Ό μ •μ˜ν–ˆλ‹€. 

이 λ©”μ„œλ“œλ“€μ„ 보면 μΈμŠ€ν„΄μŠ€ μžμ‹ μ€ μˆ˜μ •ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ Complex μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ λ°˜ν™˜ν•œλ‹€. 

 

1️⃣  ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— μ ν•©ν•˜λ‹€. 

ν”Όμ—°μ‚°μžμ— ν•¨μˆ˜λ₯Ό μ μš©ν•΄ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜μ§€λ§Œ, ν”Όμ—°μ‚°μž μžμ²΄λŠ” κ·ΈλŒ€λ‘œμΈ ν”„λ‘œκ·Έλž˜λ° νŒ¨ν„΄μ„ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄λΌκ³  ν•œλ‹€. 

(이와 λ°˜λŒ€λ‘œ 절차적 ν˜Ήμ€ λͺ…λ Ήν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” λ©”μ„œλ“œμ— ν”Όμ—°μ‚°μžμΈ μžμ‹ μ„ μˆ˜μ •ν•΄ μžμ‹ μ˜ μƒνƒœκ°€ λ³€ν•˜κ²Œ ν•œλ‹€.) 

 

 

2️⃣ λΆˆλ³€ κ°μ²΄λŠ” λ‹¨μˆœν•˜λ‹€. 

λΆˆλ³€ κ°μ²΄λŠ” μƒμ„±λœ μ‹œμ μ˜ μƒνƒœλ₯Ό 파괴될 λ•ŒκΉŒμ§€ κ·ΈλŒ€λ‘œ κ°„μ§ν•œλ‹€. 

λͺ¨λ“  μƒμ„±μžκ°€ 클래슀 λΆˆλ³€μ‹μ„ 보μž₯ν•œλ‹€λ©΄ κ·Έ 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ λ‹€λ₯Έ λ…Έλ ₯을 듀이지 μ•Šλ”λΌλ„ μ˜μ›νžˆ λΆˆλ³€μœΌλ‘œ λ‚¨λŠ”λ‹€. 

 

 

3️⃣ λΆˆλ³€ κ°μ²΄λŠ” 근본적으둜 μŠ€λ ˆλ“œ μ•ˆμ „ν•˜μ—¬ λ”°λ‘œ 동기화할 ν•„μš” μ—†λ‹€. 

λΆˆλ³€ κ°μ²΄λŠ” μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— κ³΅μœ ν•˜λ”λΌλ„ μ ˆλŒ€λ‘œ ν›Όμ†λ˜μ§€ μ•ŠλŠ”λ‹€! (κ·Έλž˜μ„œ 사싀 μŠ€λ ˆλ“œ μ•ˆμ „ν•˜κ²Œ λ§Œλ“œλŠ” κ°€μž₯ κ°„λ‹¨ν•œ 방법이기도 ν•˜λ‹€)  λΆˆλ³€ 객체에 λŒ€ν•΄μ„œλŠ” κ·Έ μ–΄λ–€ μŠ€λ ˆλ“œλ„ λ‹€λ₯Έ μŠ€λ ˆλ“œμ— 영ν–₯을 쀄 수 μ—†μœΌλ‹ˆ λΆˆλ³€ κ°μ²΄λŠ” μ•ˆμ‹¬ν•˜κ³  κ³΅μœ ν•  수 μžˆλ‹€. 

λΆˆλ³€ 객체λ₯Ό 자유둭게 κ³΅μœ ν•  수 μžˆλ‹€λŠ” 것은 방어적 볡사도 ν•„μš”μ—†λ‹€λŠ” 결둠으둜 μžμ—°μŠ€λŸ½κ²Œ 이어진닀. (원본이 κ·ΈλŒ€λ‘œ μœ μ§€λ˜λ‹ˆκΉŒ) 

 

-> λ”°λΌμ„œ λΆˆλ³€ 클래슀라면 ν•œλ²ˆ λ§Œλ“  μΈμŠ€ν„΄μŠ€λ₯Ό μ΅œλŒ€ν•œ μž¬ν™œμš©ν•˜κΈ°λ₯Ό κΆŒν•œλ‹€! 

 

 

4️⃣ λΆˆλ³€ κ°μ²΄λŠ” 자유둭게 κ³΅μœ ν•  수 μžˆμŒμ€ λ¬Όλ‘ , λΆˆλ³€ κ°μ²΄λΌλ¦¬λŠ” λ‚΄λΆ€ 데이터λ₯Ό κ³΅μœ ν•  수 μžˆλ‹€. 

 

 

5️⃣ 객체λ₯Ό λ§Œλ“€ λ•Œ λ‹€λ₯Έ λΆˆλ³€ 객체듀을 κ΅¬μ„±μš”μ†Œλ‘œ μ‚¬μš©ν•˜λ©΄ 이점이 λ§Žλ‹€. 

값이 λ°”λ€Œμ§€ μ•ŠλŠ” κ΅¬μ„±μš”μ†Œλ“€λ‘œ 이루어진 객체라면 κ·Έ ꡬ쑰가 아무리 λ³΅μž‘ν•˜λ”λΌλ„  λΆˆλ³€μ‹μ„ μœ μ§€ν•˜κΈ° 훨씬 μˆ˜μ›”ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 

ex) λΆˆλ³€ κ°μ²΄λŠ” λ§΅μ˜ν‚€μ™€ 집합(set)의 μ›μ†Œλ‘œ 쓰기에 μ•ˆμ„±λ§žμΆ€μ΄λ‹€. λ§΅μ΄λ‚˜ 집합은 μ•ˆμ— λ‹΄κΈ΄ 값이 λ°”λ€Œλ©΄ λΆˆλ³€μ‹μ΄ ν—ˆλ¬Όμ–΄μ§€λŠ”λ° λΆˆλ³€ 객체λ₯Ό μ‚¬μš©ν•˜λ©΄ 그런 걱정은 ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€. 

 

 

6️⃣ λΆˆλ³€ κ°μ²΄λŠ” κ·Έ 자체둜 μ‹€νŒ¨ μ›μžμ„±μ„ μ œκ³΅ν•œλ‹€. 

μƒνƒœκ°€ μ ˆλŒ€λ‘œ λ³€ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μž κΉμ΄λΌλ„ 뢈일치 μƒνƒœμ— 빠질 κ°€λŠ₯성이 μ—†λ‹€. 

 

 

 

λΆˆλ³€ 클래슀의 단점 

1️⃣ 값이 λ‹€λ₯΄λ©΄ λ°˜λ“œμ‹œ λ…λ¦½λœ 객체둜 λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. 

-> 이에 λŒ€ν•œ ν•΄κ²° λ°©λ²•μœΌλ‘œλŠ” "닀단계 μ—°μ‚°"을 μ œκ³΅ν•˜κ±°λ‚˜, "κ°€λ³€ λ™λ°˜ 클래슀"λ₯Ό μ œκ³΅ν•˜μ—¬ λŒ€μ²˜ν•  수 μžˆλ‹€. 

 

닀단계 연산을 μ œκ³΅ν•˜λŠ” 방법은 plus, minus, dividedBy λ©”μ„œλ“œ 같은 κ±Έ ν•œλ²ˆμ— μ œκ³΅ν•΄μ„œ 각 λ‹¨κ³„λ§ˆλ‹€ 객체λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ 되게 ν•œλ‹€. 

 

κ°€λ³€ λ™λ°˜ 클래슀의 예둜 String의 StringBuilder κ°€ μžˆλ‹€. 

public class StringExample
{
   public static void main(String[] args)
   {
      String name = "whiteShip";
      StringBuilder sb = new StringBuilder(name); // κ°€λ³€ λ™λ°˜ 클래슀λ₯Ό μ œκ³΅ν•˜μ—¬ 단점 보완 κ°€λŠ₯
      sb.append("hyejin");
   }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90