[자바] 사다리 게임 구현

2020. 5. 24. 22:47TIL/자바

로또 게임 이후 스터디에서는 사다리 게임을 구현하였다.

이제 코드컨벤션을 지키며 코딩하는 것과 로직마다 테스트 코드를 작성하는 것,

객체지향적 설계를 하는 것에 익숙해진 느낌이었다.

물론, 아무것도 몰랐던 스터디 이전의 나와 비교했을때 말이다.

이번 사다리 게임을 구현하면서 느꼈던, 배웠던 것들에 대해 정리해 보려고 한다.
(사다리 게임)

1. 객체를 이용한 2차원 배열

사다리를 구현하기 위한 구상을 하던중, 가장 이슈가 될만한 것은 역시 사다리를 어떠한 데이터 형으로 저장할 것인가 였다. 생각한 것은 역시 2차원 배열이었다. List<List> 의 형태로 만들어서, 한줄 한줄의 정보를 더하여 사다리를 만드는 것이다.

하지만 이와 같은 코드를 이용할 경우 한줄을 의미하는 코드가 어떤 것인지, 전체 사다리의 모습을 한 코드는 어떤 것인지 매우 헷갈리는 상황이 왔다. 자료형이 들어가는 곳에 List이 들어가기 때문에 그것이 의미하는 것이 무엇인지 따로 네이밍을 할 수 없는 상황인 것이다. 이에 대하여 한줄을 의미하는 List을 상태값으로 갖는 객체를 만들어서 List화 할 것을 힌트로 얻었다.

즉, 한줄을 의미하는 List line을 상태값으로 갖는 Line클래스를 정의하고 사다리 전체를 표현할때는 List으로 표현하는 것이다. 이렇게하면 Line정보에 불변성을 부여할 수 있음과 동시에 의미하는 바를 명확히 전달할 수 있는 장점이 있었다.

이 과정에서 한줄의 정보를 String으로 하는 것이 아닌 각 점이 옆에 점과 연결되어 있는지에 대한 여부를 저장하도록 바꿈으로서 좀 더 코드가 간결해졌다.

위의 코드를 보면 더 이해가 잘 갈 것이다.

List points 를 한 줄의 정보를 갖는 상태로 생각하면 된다. 이것을 private으로 해줌으로서 외부에서 이 정보를 바꿀수 없도록 해줄 수 있다.

2. 인터페이스를 활용한 설계

사다리를 생성하는 방법은 점과 점사이에 선을 랜덤으로 생성하는 방식을 사용하였다.

하지만 이렇게 랜덤으로 만들어진 사다리는 테스트를 하기 힘들다. 매번 다른 모양의 사다리가 나오기 때문에 로직이 잘 동작하는지를 검사하는 코드를 작성하는 것이 어렵기 때문이다. 따라서, 프로덕션 코드에서는 랜덤으로 사다리를 만들도록 하는 대신 테스트 코드에서는 예측 가능한 사다리가 만들어 지도록 해야한다. 이것을 인터페이스를 이용하여 구현할 수 있었다.

프로덕션 코드
테스트 코드

사다리를 만드는 LadderCreatorStrategy 인터페이스를 만들고 generate() 메소드를 정의한다.

프로덕션 코드에서는 랜덤으로 생성하기 위해 LadderCreatorStrategy를 구현한 클래스를 만들고 사용한다.

테스트 코드에서만 사용할 클래스를 프로덕션 코드에 추가하지 않기 위해 함수형 인터페이스를 사용하여 () -> true 코드를 넣어 주었다.

이렇게 인터페이스를 사용한 설계를 통해 다형성을 보장하고, 프로덕션 코드와 테스트 코드에서 각 상황에 맞추어 활용할 수 있게 하였다.

3. 로직이 없는 생성자에 대한 테스트는 생략 가능

생성자 같은 경우 어떠한 로직이 포함되어 있으면 반드시 테스트 하는 것이 좋겠다. 하지만, 아무런 로직이 없는 생성자를 테스트 하기 위해 새로운 메소드를 추가하여 사용하는 것은 바람직 하지 않을 수도 있다. 별다른 로직이없는 경우 생성자는 사실 잘못 동작할리가 없기 때문이다.

위의 예시와 같이 Line의 생성자에서는 상태를 초기화 해주는 것 외에는 아무런 로직이 없는데, 이것을 테스트 하기 위해서 checkLine이라는 메소드를 만들어서 사용하고 있다. 이 메소드가 다른곳에서도 사용된다면 모르겠지만 오로지 생성자 테스트를 위해 만들어 졌다면 '굳이'라는 느낌이 든다. 따라서, 로직이 없는 생성자를 테스트하는것만이 목적인 불필요한 메소드 생성은 하지 않는것이 좋겠다.

4. Array의 equals와 List의 equals

객체의 동등성 비교에 대해서는 이전 로또 게임 구현에 관한 글에서 정리를 하였다.

이번에는 배열과 리스트의 equals의 차이에 대해 알게되어 간단히 정리해 두려고 한다.

먼저 Array를 살펴보면 equals라는 메소드를 따로 두고있지 않다. 이것은 Object의 equals를 그대로 사용한단는 것을 의미한다. 저번에 공부했던 바에 의하면 Object의 equals를 살펴보면 가리키고 있는 주소값을 비교한다. 따라서 서로 다른 주소를 가리키고 있는 두 Array가 있을때, 모든 요소가 같다고 하더라도 equals 비교를 하면 false를 반환한다.

반면에, List 클래스를 살펴보면 아래와 같이 equals 메소드를 오버라이드 하고 있다.

따라서 List같은경우 equals로 비교를 하였을때, 가지고 있는 요소들이 모두 같은지를 비교하여 true 또는 false를 반환해 준다.

이것을 고려하여 같은 요소를 가진 List인지를 테스트할 때 따로 오버라이드 하지않고 equals메소드를 사용할 수 있었다.

'TIL > 자바' 카테고리의 다른 글

[자바] 로또 게임 구현  (0) 2020.05.18
[자바] Java와 JVM  (0) 2020.05.06
[자바] getter메소드 사용을 지양하자  (0) 2020.04.25
[테스트] JUnit 과 AssertJ  (0) 2020.04.23
[자바] 레이싱 게임 구현  (0) 2020.04.22