wonslee / object-study

📔오브젝트 예제 코드를 따라 공부, 토론하는 스터디 그룹
0 stars 1 forks source link

4장 공부 내용 #17

Open kmw2378 opened 6 months ago

kmw2378 commented 6 months ago

블로그 정리 + 우테코 자동차 경주 미션을 리펙토링했습니다!

블로그 링크

리펙토링 코드

V1 (캡슐화 X, 낮은 응집도, 높은 결합도)

Car.java

public class Car {
    private String name;
    private Position position;

    public Car(final String name, final Position position) {
        this.name = name;
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(final Position position) {
        this.position = position;
    }
}

Position.java

public class Position {
    private int value;

    public Position(final int value) {
        this.value = value;
    }

    public void plus(final int value) {
        this.value += value;
    }
}

Racing.java

public class Racing {
    private List<Car> cars;

    public Racing(final List<Car> cars) {
        this.cars = cars;
    }

    public void race(final int attempt) {
        IntStream.range(0, attempt)
                .forEach(i -> raceOneTime());
    }

    private void raceOneTime() {
        cars.forEach(car -> {
            final int randomNumber = Randoms.pickNumberInRange(0, 9);
            if (randomNumber > 4) {
                car.getPosition().plus(1);
            }
        });
    }
}

"자동차를 전진하라" 라는 로직에 대한 책임을 Racing, Car, Position 모두 갖고 있습니다. 이는 응집도가 낮고 의존성이 높다고 볼 수 있습니다. 만약, 자동차의 위치에 좌표가 추가된다면 이것이 Racing 객체까지 전파되므로 유연하지 못한 코드라 생각합니다.

V2 (개선)

Car.java

public class Car {
    private String name;
    private Position position;

    public Car(final String name, final Position position) {
        this.name = name;
        this.position = position;
    }

    public void plusPosition(final int randomNumber) {
        if (randomNumber > 4) {
            position.plus(1);
        }
    }
}

Position.java

public class Position {
    private int value;

    public Position(final int value) {
        this.value = value;
    }

    public void plus(final int value) {
        this.value += value;
    }
}

Racing.java

public class Racing {
    private List<Car> cars;

    public Racing(final List<Car> cars) {
        this.cars = cars;
    }

    public void race(final int attempt) {
        IntStream.range(0, attempt)
                .forEach(i -> raceOneTime());
    }

    private void raceOneTime() {
        cars.forEach(car -> {
            final int randomNumber = Randoms.pickNumberInRange(0, 9);
            car.plusPosition(randomNumber);
        });
    }
}

기존 V1에서 RacingPosition 사이의 의존성을 제거하면서 결합도를 낮췄습니다. 또한, "자동차를 전진시켜라" 라는 로직에 대한 책임을 기존 3개에서 2개의 객체만 갖게 되어 응집도가 높아졌습니다.

이 외에 개선할 점

일급 컬렉션을 도입한다면 더욱 캡슐화가 강해질 것 같습니다. 랜덤 번호를 부여하는 객체를 고려한다면 추후 이에 대한 변경사항이 생길 때 파급효과를 최소화할 수 있을 것 같습니다!