8장. 객체 만들기

변주한·2022년 6월 8일
0

$5 + 10 CHF = $10(환율이 2:1일 경우)
$5 X 2 = $10
amount를 private으로 만들기
Dollar 부작용(side effect)?
Money 반올림
equals()
hashcode()
Equal null
Equal object
5CHF X 2 = 10CHF
Dollar/Franc 중복
공용 equals
공용 times
Franc과 Dollar 비교하기
통화?

두 times() 구현 코드가 거의 똑같다.

	public Money times(int multiplier) {
       return new Dollar(amount * multiplier);
   }
   
   public Money times(int multiplier) {
       return new Franc(amount * multiplier);
   }

양쪽 반환값을 Money로 바꿔주었다.

하위 클래스렝 대한 직접적인 참조가 적어진다면 하위 클래스를 제거하기 위해 한 발짝 더 다가섰다고 할 수 있겠다.
Money에 Dollar 반환하는 팩토리 메서드를 도입하자.

public class Dollar extends Money{

   public static Dollar dollar(int amount) {
       return new Dollar(amount);
   }
   .
   .
   .
   
}

@Test
public void testMultiplication(){
	Dollar five = Dollar.dollar(5);
	assertEquals(new Dollar(10), five.times(2));
	assertEquals(new Dollar(15),five.times(3));
}
   

Dollar에 대한 참조가 사라지길 바라므로 테스트의 dollar 타입 선언부를 Money로 바꾸자

@Test
public void testMultiplication(){
	Money five = Dollar.dollar(5);
	assertEquals(new Dollar(10), five.times(2));
	assertEquals(new Dollar(15),five.times(3));
}


public abstract class Money {
    protected int amount;
    abstract Money times(int multiplier);
	.
    .
    .
    .
}

Franc도 동일한 방식으로 수정

일단 테스트 코드 수정

@Test
    public void testMultiplication(){
        Money five = Dollar.dollar(5);
        assertEquals(Dollar.dollar(10), five.times(2));
        assertEquals(Dollar.dollar(15),five.times(3));
    }

    @Test
    public void testEquality(){
        assertTrue(Dollar.dollar(5).equals(Dollar.dollar(5)));
        assertFalse(Dollar.dollar(5).equals(Dollar.dollar(6)));

        assertTrue( Franc.franc(5).equals( Franc.franc(5)));
        assertFalse( Franc.franc(5).equals( Franc.franc(6)));

        assertFalse( Franc.franc(5).equals(Dollar.dollar(5)));
    }

    @Test
    public void testFrancMultiplication(){
        Franc five = Franc.franc(5);
        assertEquals( Franc.franc(10), five.times(2));
        assertEquals( Franc.franc(15), five.times(3));
    }

Franc의 팩토리 메서드 추가

public class Franc extends Money{
    public Franc(int amount) {
        this.amount = amount;
    }

    public static Franc franc(int amount) {
        return new Franc(amount);
    }

    public Money times(int multiplier) {
        return new Franc(amount * multiplier);
    }
}
  • 동일한 메서드(times) 두 변이형 메서드 서명부를 통일시킴으로써 중복제거를 향해 한 단계 더 전진했다.
  • 최소한 메서드 선언부만이라도 공통 상위 클래스(superclass)로 옮겼다
  • 팩토리 메서드를 도입하여 테스트 코드에서 콘크리트 하위 클래스의 존재 사실을 분리해냈다.
  • 하위 클래스가 사라지면 몇몇 테스트는 불필요한 여분의 것이 된다는 것을 인식했다. 하지만 일단 그냥 뒀다.
profile
늦었지만 꾸준히

0개의 댓글