본문 바로가기
Java

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

by bkuk 2023. 4. 25.
해당 글은 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' 메서드를 오버라이드 함으로써, 주소값을 비교하지 않고, 값을 비교하는 것이 가능해졌다.

 

댓글