###고민한 것들
플레이어가 승리하였는지 확인하는 방법에 대해서 고민이 조금 있었습니다.
코드를 짜기 시작할때는, 굉장히 그래프형태에 걸맞는다고 생각했지만..
지금 생각하면 굳이 bfs를 썼어야했나 싶네요.
그리고 클래스를 어느부분까지 세분화하여야 하는지 또한 고민이 되었습니다.
저는 두가지로 나누었지만, 더 세분화가 가능할 것 같습니다.
협력, 역할, 책임에 초점을 맞추었습니다.
특히 행동을 먼저 정의하고 이후의 것을 구현하였습니다.
또한 객체의 자율성을 위하여 제가 할 수 있는(제가 생각하는) 캡슐화를 해주었습니다.
다만, UML? ERD? 그래프(?)를 어떻게 그리고 객체를 표현해주어야할지 모르겠습니다..
가능하시다면 검색어라도 추천해주시면 감사하겠습니다.
외부 객체에서 다른 객체로의 setter는 사용하지 않았습니다.
코드 자체는 길어지지만, 패키지로 구분하면 충분히 메리트있을 만하다고 생각합니다.
유지보수 측면에서도 필요한 부분만 변경하면 되고, 특히 tictactoe의 main메서드는
플레이 순서가 변경되지 않는 이상 변경되지 않게 하였습니다.
조언해주시면 너무나 감사하겠습니다!!ㅎㅎ😆
<객체 표현 그래프..?>
https://miro.com/app/Board/uXjVORrKiB4=/?invite_link_id=506617187893
피드백 해주신 것을 토대로 수정하였습니다.
도메인과 서비스를 나누었고,
제가 제대로 이해한 것이 맞는지는 불확실하지만, Container 클래스를 생성하였습니다.
질문 몇가지가 생겨, 여쭙니다..!
- 굳이 객체를 생성할 필요가 없다고 느껴져 static으로 자꾸 사용하게 되는데.. 이렇게 설계하는 것이 올바른 것인지 궁금합니다.
- Container클래스를 생성하는 것이, 스프링의 IoC와 같이 싱글톤을 위함인 것인지 궁금합니다. 저는 그렇게 해석하여서, 공통으로 사용해야하는 것들은 Container에 집어 넣었는데, 올바르게 한 것인지 궁금합니다. jpa의 영속성 컨텍스트 처럼 사용하였습니다. 대표적으로 ArrayList players의 경우가 그렇습니다.
- public과 private를 제가 잘 사용한 것인지 궁금합니다.
- 물론 여기서 그리 크지는 않지만, 시간복잡도가 커진 것이 아닌지.. 혹은.. 비효율적으로 짠 것이 아닌지..
: 물론 제가 무지한 것이기는 합니다만.. 간단한 것을 제가 생각하는 객체지향적으로 풀어내고자 하다보니, 다소 더 간단한 코드로 해결 가능한 것이 복잡해지는 듯합니다.. 어떻게 해야할까요..?
: 예시 - playerService.getPlayerIdentifierByIndex 와 이것을 사용하는 과정..
: 예시 - victoryStrategies를 referee가 가지고 있는 것이 referee의 역할에 맞다고 생각하여 victorystragies를 가지고 있지만, 정작 checkWinner()메서드에 전달할 때만 사용하는 것..(애초에 CheckWinnerClass에서 victorystragies를 가지고 있으면 굳이 없어도 될 코드..)
: 원래 이런 것인가요..?
이외에도 다음 피드백에서 제가 제대로 수정한 것인지 궁금합니다.
- List로 선언한 것 아주 좋습니다! 근데 new ArrayList<>();로 받으니 referee 클래스가 구체적인 것에 의존하게 되었어요 ㅎㅎ... 의존성 주입으로 받으면 좋을 것 같습니다.
- referee는 checkWinner, checkContinue 등 여러 책임을 가지고 있는데 이를 인터페이스로 분리를 하지 않으면
역할 A = new 구현();형식으로 받을 수가 없어요. 즉 OCP, DIP에 위반될 것 같습니다! - 프로그램에서는 생성과 초기화, 처리 로직을 분리하는게 좋아요. 생성과 초기화를 담당하는 클래스를 만들면 좋겠습니다. 이를 이용하면 OCP, DIP를 초기화할 수 있어요. 다음은 간단한 예시 입니다~.
- 도메인(엔티티)과 비지니스 로직을 분리하면 좋을 것 같아요.