> For the complete documentation index, see [llms.txt](https://koseungbin.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://koseungbin.gitbook.io/wiki/books/undefined-3/1/undefined-1.md).

# 모두를 위한 평등

## 또 다른 오퍼레이션&#x20;

Dollar 부작용을 값 객체를 사용하여 해결하였다. 여기서, 값 객체는 또 다른 오퍼레이션인 equals() 를 구현해야한다는 것을 암시한다. 따라서 equals() 오퍼레이션에 대한 테스트를 진행해보자.

{% tabs %}
{% tab title="테스트 목록" %}

* $5 + 10CHF = $10(환율이 2:1 일 경우) &#x20;
* ~~*$5 \** 2 = 10$~~&#x20;
* *amount를 private으로 만들기*&#x20;
* ~~Dollar 부작용(side effect)?~~&#x20;
* &#x20;Money 반올림?
* **equals()**
* hashCode()
  {% endtab %}
  {% endtabs %}

값 객체의 동치성을 비교하기 위한 테스트 시나리는 아래와 같다.

```java
@Test
void testEquality() {
    assertTrue(new Dollar(5).equals(new Dollar(5)));
    
}
```

�컴파일은 성공하지만, 테스트에 실패하는 것을 확인할 수 있다.&#x20;

![](https://1360705058-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LZ0r85EEFTHmLyxK8ag%2F-LsbJeizIAHuTofpTI1V%2F-LseS_poUnO1CQTkWOBe%2Fimage.png?alt=media\&token=505ec9b1-670d-4f52-aa4e-4cd6ca761d0d)

빠르게 초록 막대를 보기 위해 가짜 구현을 해보자.

```java
public boolean equals(Object object) {
    return true;

}
```

![](https://1360705058-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LZ0r85EEFTHmLyxK8ag%2F-LsbJeizIAHuTofpTI1V%2F-LseTfJRG8eWtaKXEfA-%2Fimage.png?alt=media\&token=e2c02a28-189c-42a2-9186-7fd67518bc6b)

다행히 초록막대까지 볼 수 있게 되었다. 이제 리팩토링을 해야한다.

사실 true 값은 다음과 같은 단계를 밟아 일반화할 수 있다.

1. 5 == 5
2. amount == 5
3. amount == dollar.amount

이러한 명확한 케이스의 경우에는 위와 같이 쉽게 일반화할 수 있으나, 그렇지 않은 경우에는 켄트벡은 **삼각 측량 전략**을 제시해준다.

## 삼각 측량

삼각 측량 전략을 핵심은 **유추**이다.  두 개 이상의 예제를 통해서 코드를 일반화해 나가는 것이며, 새로 추가된 예제가 일반적인 해를 필요로 할때만 비로소 일반화한다.&#x20;

책에서 "새로 추가된 예제가 일반적인 해를 필요할 때만 일반화한다." 라는 문장이 이해가 되질 않았다. 개인적인 해석으로 비추어보면, 현재 구체적으로 작성된 코드 상황에서 **"필요한 만큼만 점진적으 일반화(확장) 하라"는** 의미로 생각하였다. 현재 상황에 불필요한 정도로 일반화를 시키게 되면 예기치 못한 버그를 발생시킬 있기 때문이다.

또한, 켄트벡은 **어떻게 리팩토링, 설해야 할지 전혀 감이 오질 않을 때 삼각측량 전략을 사용**한다고 말한다. 굳이 삼각측량 방법만이 아닌, 코드와 테스트의 중복을 제거하고 일반적인 해법이 존재할 경우에는 그 방법을 구현하면 된다는 것이다.

```java
@Test
void testEquality() {
    assertTrue(new Dollar(5).equals(new Dollar(5)));
    assertFalse(new Dollar(5).equals(new Dollar(6)));

}
```

테스트는 당연히 실패할 것이다.

![](https://1360705058-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LZ0r85EEFTHmLyxK8ag%2F-LsbJeizIAHuTofpTI1V%2F-LseWS92bF1-Gd8iawTs%2Fimage.png?alt=media\&token=42449521-9f5e-4fea-ba0e-09bcefe9deda)

이제 동치성을 일반화해야 한다.

```java
public boolean equals(Object object) {
    Dollar dollar = (Dollar) object;
    return amount == dollar.amount;

}
```

�초록막대를 볼 수 있을 것이다.

![](https://1360705058-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LZ0r85EEFTHmLyxK8ag%2F-LsbJeizIAHuTofpTI1V%2F-LseXQA8Y50md8qKkhwk%2Fimage.png?alt=media\&token=48b9c9a3-deb6-45c6-b673-76384d8bc42c)

지금까지 동일성 문제는 일시적으로 해결됐다. 하지만, 현재 프로그램이 어떤 **변화 가능성**을 지원해야 하는가? 몇몇 부분을 변경시켜보면 답이 명확해질 것이다.

* Null or 다른 객체들과 비교한다면?

이런 상황은 지금 당장 필요하지 않으므로 할일 목록에 적어두기만 하자.

{% tabs %}
{% tab title="테스트 목록" %}

* $5 + 10CHF = $10(환율이 2:1 일 경우) &#x20;
* ~~*$5 \** 2 = 10$~~&#x20;
* *amount를 private으로 만들기*&#x20;
* ~~Dollar 부작용(side effect)?~~&#x20;
* &#x20;Money 반올림?
* ~~equals()~~
* hashCode()
* Equal null
* Equal object
  {% endtab %}
  {% endtabs %}
