Java

[Java] 상태 데이터를 get하지 말고 메시지를 보내라.

bkuk 2023. 4. 25. 15:12
해당 글은 NEXTSTEP 자바 플레이그라운드 with TDD, 클린 코드를 통해서 새롭게 배우고 내용을 기록한 글입니다.

 

상태 데이터를 get하지 말고, 메시지를 보내라

상태 데이터를 get 하지말라는 말의 의미를 이해해보자.

public class Winners {
    private final List<Car> cars;
    
    private List<Car> findWinners(int maxPositionValue) {
        List<Car> winners = new ArrayList<>();
        for( Car car : cars ) {
            if( car.getPosition() == maxPositionValue)
                winners.add(car);
        }
        return winners;
    }
}

 

위 코드를 이해해보자.

  • 'finWinners' 메서드는 최대 위치 값인 'maxPositionValue' 를 인자로 전달받아, 클래스변수 'cars' 리스트에 해당 위치 값과 일치하는 자동차 객체를 추가하고, 이를 반환한다.
  • 'for-each' 루프를 이용해서 각 'car' 객체에 대해서 순회한다.
  • 이때, 'if' 문을 사용해서 'car' 객체의 위치 값인 'car.getPosition()'이 전달받은 'maxPositionValue'와 일치하는지 확인한다.

 

Car 객체에서 데이터(Position)를 꺼내서 확인하고 있다. 

상태 데이터를 가지는 Position 객체가 일하도록 변경해보면 어떨까?

예를 들면 "Car야. 너 혹시 Winner이니?" 라는 의미가 담긴 메서드로, Car에게 메시지를 보내는 것이다. 

private List<Car> findWinners(Position maxPositionValue) {
    List<Car> winners = new ArrayList<>();
    for( Car car : cars ) {
        if( car.isWinner(maxPositionValue) )
            winners.add(car);
    }
    return winners;
}

위처럼 Car 객체에 메세지를 보내는데, 'isWinner()'라는 제목에, 'maxPositionValue'라는 내용을 같이 전달한다면 된다.

 

그럼 이제, Car 객체에 클래스로 가보자.

public class Car {
    private int position;
    // 생략..

원래는 데이터 타입인 'int'형인 'position'인 지역변수가 있었지만,

 

public class Car {
    private Position position;
    // 생략..

이를(원시값) 포장한 객체인 Position에 지역변수로 존재한다.

 

따라서, Position 객체에 한번 더 메세지를 보내야한다.

이때 내용은 그대로 보내도 괜찮지만, 제목은 어떻게 해야할까?

위에서 Winners 객체와 Car 객체와의 관계를 생각해서 isWinner() 라는 제목으로 작성했다.

Car 객체와 Position 객체와의 관계를 생각하면 "Position야. 혹시 이 숫자랑 같니?" 라는 제목으로 작성하자.

public class Car {
    private Position position;
    
    public boolean isWinner(Position maxPositionValue) {
            return position.isSame(maxPositionValue);
    }

 

그렇다면. Position 객체에서는 이를 아래와 같이 구현이 가능하다. 

public class Position {
    private int position;
    
    public boolean isSame(Position maxPositionValue) {
        return this.position == maxPositionValue.position;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(position);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Position other = (Position) obj;
        return position == other.position;
    }
    
    // 생략..

 

'equals' 메서드를 오버라이드 함으로써, 주소값을 비교하지 않고, 값을 비교하는 것이 가능해졌다.