데이터 종속 같은 거 수작업으로 코드 정리 하다가 동작 변경까지 해버릴 수 있는데, 두려워하지 마라. 올바른 코드로 되돌리면 되고, 작은 단계로 작업하면 된다. 커다란 설계 변경을 하지 말고 두려움을 느끼지 않는 수준까지 작게 쪼개어 작업해라.
코드 정리에 대한 커밋과 동작 변경에 대한 커밋은 분리해야 한다
코드를 만드는 데 가장 큰 비용이 들어가는 일은, 코드 작성이 아니라 읽고 이해하는 데 드는 비용이다. 코드 정리를 선행하면 더 작은 조각 단위로 결합을 제거하는 길을 제시하여 응집도를 높일 수 있다. 한 번에 머릿속에 기억하고 있어야 할 코드의 상세 내용도 줄여준다.
호출하는 모든 코드를 정리하는 일은 무의미하지 않다. 새로운 API 전환에 따라 영향을 받는 코드 모두를 변경하고 나면, 어떤 클래스들은 변경하기가 훨씬 쉬워진다.
코드 정리를 선행해야 할까? 상황에 따라 다르다
설계 결정이 코드 베이스 전체에 전파될 때도 있다. integer 타입 정수를 long 타입으로 변경했더니 백만 개의 변경이 필요한 것처럼. 1) 이 결정이 확산될 가능성이 있는 결정인지에 대해 좀 더 생각해보고, 2) 그런 일이 발생하면, 한 번에 하나씩 정리해나가라.
한 종류의 코드 변경에 대한 결합도를 줄일 수록 다른 종류의 코드 변경에 대한 결합도가 커진다.
어제 못했던 InputHandler.cs도 떼어냈다
GameManager.cs가 68줄로 줄어들어 진정한 '매니저' 스크립트가 되었다.
public class GameManager : MonoBehaviour
{
private Board board;
private MoveValidator moveValidator;
private InputHandler inputHandler;
private IGameState currentState; // 현재 활성 상태
public bool whiteTurn = true; // 턴을 나타내는 변수
// 상태 스크립트 인스턴스들
[HideInInspector] public WhiteTurnState whiteTurnState;
[HideInInspector] public BlackTurnState blackTurnState;
// [HideInInspector] public PlayerTurnState playerTurnState;
// [HideInInspector] public AiTurnState aiTurnState;
void Start()
{
SetComponents();
board.SetBoard();
whiteTurnState = new WhiteTurnState(this);
blackTurnState = new BlackTurnState(this);
currentState = whiteTurnState;
}
void SetComponents()
{
GameObject serviceLocator = GameObject.FindGameObjectWithTag("ServiceLocator");
board = serviceLocator.GetComponentInChildren<Board>();
moveValidator = serviceLocator.GetComponentInChildren<MoveValidator>();
inputHandler = serviceLocator.GetComponentInChildren<InputHandler>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
inputHandler.HandleClick(whiteTurn);
}
currentState.UpdateState();
}
public void EndTurn()
{
moveValidator.ResetEnPassantCandidates(whiteTurn);
ChangeState();
}
void ChangeState()
{
if (currentState != null)
{
currentState.ExitState();
}
currentState = whiteTurn ? whiteTurnState : blackTurnState;
whiteTurn = !whiteTurn;
currentState.EnterState();
}
}