item 23 hyowon - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

νƒœκ·Έ 달린 ν΄λž˜μŠ€λž€

두 가지 μ΄μƒμ˜ 의미λ₯Ό ν‘œν˜„ν•  수 있으며, 그쀑 ν˜„μž¬ ν‘œν˜„ν•˜λŠ” 의미λ₯Ό νƒœκ·Έ κ°’μœΌλ‘œ μ•Œλ €μ£ΌλŠ” 클래슀

public class Figure {
    enum Shape { RECTANGLE, CIRCLE };
    
    // νƒœκ·Έ ν•„λ“œ - ν˜„μž¬ λͺ¨μ–‘을 λ‚˜νƒ€λ‚Έλ‹€.
    final Shape shape;
    
    // λ‹€μŒ ν•„λ“œλ“€μ€ λͺ¨μ–‘이 μ‚¬κ°ν˜•μΌ λ•Œλ§Œ 쓰인닀.
    double length;
    double width;
    
    // λ‹€μŒ ν•„λ“œλŠ” λͺ¨μ–‘이 μ›μΌλ•Œλ§Œ 쓰인닀.
    double radius;
    
    // μ›μš© μƒμ„±μž
    Figure(double radius) {
        shape = Shape.CIRCLE;
        this.radius = radius;
    }
    
    // μ‚¬κ°ν˜•μš© μƒμ„±μž
    Figure(double length, double width) {
        shape = Shape.RECTANGLE;
        this.length = length;
        this.width = width;
    }
    
    double area() {
        switch (shape) {
            case RECTANGLE:
                return length * width;
            case CIRCLE:
                return Math.PI * (radius * radius);
            default:
                throw new AssertionError(shape);
        }
    }
}

νƒœκ·Έ 달린 클래슀의 단점

  1. 쓸데 μ—†λŠ” μ½”λ“œκ°€ λ§Žλ‹€.(μ—΄κ±° νƒ€μž…, νƒœκ·Έ ν•„λ“œ, switchλ¬Έ...)
  2. μ—¬λŸ¬ κ΅¬ν˜„μ΄ ν•œ ν΄λž˜μŠ€μ— ν˜Όν•©λΌ μžˆμ–΄μ„œ 가독성도 λ‚˜μ˜λ‹€. (SRPμœ„λ°˜)
  3. λ‹€λ₯Έ 의미λ₯Ό μœ„ν•œ μ½”λ“œλ„ ν•¨κ»˜ν•˜λ‹ˆ λ©”λͺ¨λ¦¬λ₯Ό 많이 μ‚¬μš©ν•œλ‹€.
  4. ν•„λ“œλ₯Ό final μ„ μ–Έν•  λ•Œλ„ λ‹€λ₯Έ 의미λ₯Ό μœ„ν•œ ν•„λ“œλ“€λ„ final μ„ μ–Έ ν›„ μ΄ˆκΈ°ν™” ν•΄μ•Όν•΄ λΆˆν•„μš”ν•œ μ½”λ“œκ°€ λŠ˜μ–΄λ‚œλ‹€.
  5. μƒμ„±μžκ°€ νƒœκ·Έ ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ”λ° μ»΄νŒŒμΌλŸ¬κ°€ μ—λŸ¬λ₯Ό μž‘λŠ”λ° 도움 μ£ΌκΈ°κ°€ μ–΄λ ΅λ‹€. (λŸ°νƒ€μž„ μ‹œμ—λ‚˜ 였λ₯˜κ°€ λ°œκ²¬λœλ‹€.)(?)

β†’ ν•œ λ§ˆλ””λ‘œ, νƒœκ·Έ 달린 ν΄λž˜μŠ€λŠ” μž₯ν™©ν•˜κ³ , 였λ₯˜λ₯Ό λ‚΄κΈ° 쉽고, λΉ„νš¨μœ¨μ μ΄λ‹€.

λŒ€μ•ˆ

νƒœκ·Έ 달린 클래슀λ₯Ό 클래슀 계측ꡬ쑰λ₯Ό ν™œμš©ν•˜λŠ” μ„œλΈŒ 타이핑(sub-typing)으둜 λ³€κ²½

  1. 계측 ꡬ쑰의 λ£¨νŠΈκ°€ 될 좔상 클래슀λ₯Ό μ •μ˜ ν›„,
    • νƒœκ·Έ 값에 따라 λ™μž‘μ΄ λ‹¬λΌμ§€λŠ” λ©”μ„œλ“œλ“€μ„ 좔상 λ©”μ„œλ“œλ‘œ μ„ μ–Έ
    • νƒœκ·Έ 값에 상관 없이 λ™μž‘μ΄ μΌμ •ν•œ λ©”μ„œλ“œλ₯Ό 일반 λ©”μ„œλ“œλ‘œ μΆ”κ°€
    • λͺ¨λ“  ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” ν•„λ“œλ„ μΆ”κ°€ν•œλ‹€.
  2. 루트 클래슀λ₯Ό ν™•μž₯ν•œ ꡬ체 클래슀λ₯Ό μ˜λ―Έλ³„λ‘œ ν•˜λ‚˜μ”© μ •μ˜ν•œλ‹€.
abstract class Figure {
    abstract double area();
}

class Circle extends Figure {
    final double radius;
    
    Circle(double radius) { this.radius = radius; }

    @Override double area() { return 0; }
}

class Rectangle extends Figure {
    final double length;
    final double width;
    
    Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
    
    @Override double area () { return length * width; }
}

κ°„κ²°ν•˜κ³  λͺ…ν™•ν•˜λ©° μ“Έλ°μ—†λŠ” μ½”λ“œλ„ λͺ¨λ‘ μ‚¬λΌμ‘Œλ‹€.

νƒœκ·Έ 달린 클래슀의 단점을 ν•΄κ²°ν–ˆλŠ”λ°,

  1. 각 의미λ₯Ό λ…λ¦½λœ ν΄λž˜μŠ€μ— λ‹΄μ•„ κ΄€λ ¨ μ—†λ˜ 데이터 ν•„λ“œλ₯Ό λͺ¨λ‘ 제거
  2. 살아남은 ν•„λ“œλ“€μ€ λͺ¨λ‘ final이닀.
  3. 컴파일 νƒ€μž„μ— final ν•„λ“œκ°€ μ΄ˆκΈ°ν™”λλŠ”μ§€, 좔상 λ©”μ„œλ“œκ°€ κ΅¬ν˜„λλŠ”μ§€ μ²΄ν¬λœλ‹€.(switchλ¬Έ 제거)
  4. 루트 클래슀의 μ½”λ“œλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³ λ„ λ…λ¦½μ μœΌλ‘œ 계측ꡬ쑰λ₯Ό ν™•μž₯ κ°€λŠ₯ν•˜λ‹€. (OCP 원칙 μΆ©μ‘±)
  5. νƒ€μž…μ΄ μ˜λ―Έλ³„λ‘œ λ”°λ‘œ μ‘΄μž¬ν•˜λ‹ˆ λ³€μˆ˜μ˜ 의미λ₯Ό λͺ…μ‹œν•˜κ±°λ‚˜ μ œν•œν•  수 있고, 또 νŠΉμ • 의미만 λ§€κ°œλ³€μˆ˜λ‘œ 받을 수 μžˆλ‹€.
  6. νƒ€μž… μ‚¬μ΄μ˜ μžμ—°μŠ€λŸ¬μš΄ 계측 관계λ₯Ό λ°˜μ˜ν•  수 μžˆμ–΄μ„œ μœ μ—°μ„±, μ»΄νŒŒμΌνƒ€μž„ νƒ€μž… 검사 λŠ₯λ ₯을 λ†’μ—¬μ€€λ‹€.
// μ§μ‚¬κ°ν˜• μ•„λž˜μ— μ •μ‚¬κ°ν˜•
class Square extends Rectangle {
		Square(double side) {
				super(side, side);
		}
}

κ²°λ‘ 

νƒœκ·Έ 달린 ν΄λž˜μŠ€λ³΄λ‹€λŠ” 계측 ꡬ쑰둜 μ½”λ“œλ₯Ό μ§œλ„λ‘ ν•˜μž.