장's 개발생각

[개발생각] 리세마라 : 다시해보는 우테코 5기 2주차

장아장 2022. 11. 26. 13:57

한짤 요약

 

Source Code : https://github.com/JangAJang/WoowaCourse_Preview/tree/main/2주차_숫자_야구_게임_re

 

사건의 발단 :

사건의 과정 : 

결과 : 

 

이전에 풀었던 2주차 프리코스를 다시 한번 풀어보았다. 

일단 써보고 이전의 코드를 다시 보며 느낀점을 요약해보아야 겠다. 

 

모델에 서비스라는 로직을 잘못생각하고 이전 2주차를 풀었다. 모델과 서비스가 아니라, 도메인이라는 기능을 하는 가장 작은 단위와 이들의 로직이 동작하는 모델이 존재하고, 이 모델을 컨트롤러에서 불러와 뷰와 연결시킨다. 결국, 객체의 동작 과정은
모델 -> 서비스 -> 컨트롤러 -> 뷰 -> 컨트롤러 -> 서비스 -> 모델 로 모델이 여러개 존재하는 방식으로 정리했었던 과거의 구조에서, 도메인들이 모인 모델 -> 컨트롤러 -> 뷰 -> 컨트롤러 -> 모델로 동작하게 되었다. 이를 통해 도메인에 직접 들어가 일을 처리하기보단, 도메인이 일에 대한 결과들을 가져와 이를 모델이 필요할 때 쓸 수 있게 하는 동작이 되어야 했던 것 같다. 
말 참 더럽게 어렵네. 예시를 들어보자. 

public class Baseball {

    private static final int THREE_STRIKE = 3;

    private final RandomNumbers randomNumbers;
    private Player player;

    public Baseball(){
        randomNumbers = new RandomNumbers();
    }

    public void createPlayer(String input){
        player = new Player(input);
    }

    public int countStrikeWithPlayer(){
        return randomNumbers.countStrike(player.getNumbers());
    }

    public int countBallWithPlayer(){
        return randomNumbers.countBall(player.getNumbers());
    }

    public boolean isThreeStrike(){
        return countStrikeWithPlayer() == THREE_STRIKE;
    }
}

이번에 작성한 모델이다. 모델에서 도메인들을 불러와 도메인 메서드의 값을 통해 원하는 값들을 얻어올 수 있게 했다.

 

이전의 구조를 보면,

public class GameService {

    Player player;
    Computer computer;
    private int strikeCount;
    private int ballCount;
    private static final int FIRST_INDEX = 0;
    private static final int LAST_INDEX = 2;

    public void setPlayer(String input) {
        player = new Player();
        player.setNumbers(input);
    }

    public void setComputer() {
        computer = new Computer();
        computer.makeThreeDigitNumber();
    }

    public int getStrikeCount() {
        return strikeCount;
    }

    public int getBallCount() {
        return ballCount;
    }

    public void initializeScore(){
        strikeCount = 0;
        ballCount = 0;
    }

    public void checkComputerWithPlayerNumber(){
        for(int index = FIRST_INDEX; index <= LAST_INDEX; index++){
            scoreGameWithIndex(index);
        }
    }

    private List<Integer> getPlayerNumbers(){
        return player.getNumbers();
    }

    private List<Integer> getComputersNumbers(){
        return computer.getNumbers();
    }

    private void scoreGameWithIndex(int index){
        if(isStrike(index)) increaseStrike();
        if(isBall(index)) increaseBall();
    }

    private boolean isStrike(int index){
        return getPlayerNumbers().get(index)
                .equals(getComputersNumbers().get(index));
    }

    private boolean isBall(int index){
        return !isStrike(index) && getComputersNumbers().contains(getPlayerNumbers().get(index));
    }

    private void increaseStrike(){
        strikeCount++;
    }

    private void increaseBall(){
        ballCount++;
    }
}

 이런식으로 서비스라는 로직 하나에 너무 많은 기능들이 몰려있다. 

각 기능을 하는 도메인이 정확히 무엇인지 알고, 이들에 따라 분리를 했어야 했는데 이에 대한 부족함이 느껴졌다. 

또한, 이게 서비스가 맞을까 하는 생각이 들었다.

여려 정보를 취득해본 결과, 서비스는 비즈니스 로직을 수행한다. 라는게 가장 주된 임무였다. 

이는 데이터의 생성, 표시, 수정, 삭제, 즉 CRUD 시스템을 수행하는데 필요한 부분들을 등록한다. 

그런데, DB를 사용하지 않는 우테코의 과제들에서 서비스의 필요가 있을까?

절대 없다고 생각한다. 

 

서비스가 아닌, 자바의 기준으로 말하자면 클래스를 원하는 입력값으로 생성하고, 이들에 따른 결과를 도출시키는 것은 도메인의 영역에서, 그리고 원하는 값을 이용해 결국적으로 이 애플리케이션에서 필요한 결과를 만드는 것을 모델에서 수행하는게 더 좋다고 생각한다. 

 

이 부분을 가장 크게 느꼈다. 

 

사실 사진이랑 코드가 많아서 그렇지 내용을 별게 없네...

그래도 마음에 든다. 기능별로 나누었을 때 각 로직들이 누가 결국 일해서 얻어내는 것인가를 생각하고, 이를 구현하는데 더 고려해야겠다. 

뭔가 물리적인 생각보단 논리성에 대한 생각이 늘어난다.

그럴 수록 코드가 물리적으로만 동작하는 코드에서 논리적으로도 이해 가능한 코드가 될 수 있다고 믿는다. 

 

다음 주차도 열심히 해봐야지🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥