API and Package Structuring

What this lesson covers

This lesson critiques the tic-tac-toe code written in the previous video and begins restructuring it. The first problem it points out is duplication: rows, columns and diagonals are all checked for completion in nearly identical ways. Rather than jumping straight to a fix, the video stresses building an intuition for where code can be improved. The second problem is that every class lives in one file, which makes changes risky and encourages tight coupling, for example GameResult objects being constructed with new inside the completion logic. The first refactor moves each class into its own file using the IDE. This changes little functionally, but it lets developers work on classes separately. The lesson then explains APIs as the only way other code should read or change a system's state. Using an array as an example, it shows how routing changes through a function allows validation, so the data behaves the way its owner intends rather than however callers choose. The main class becomes a GameEngine class holding the start, move and completion APIs, with no main function. Board, Move and GameResult go into a game package. Player is also placed there after weighing a separate user package for things like profile settings or statistics. TicTacToeBoard moves into a boards package. Because the board's cells are no longer accessible from another package, the engine must call a getter instead, showing how package structure itself enforces encapsulation.

  • Spotting duplication and coupling comes before deciding on the fix
  • Moving classes into separate files lets developers change them independently
  • APIs restrict how other code changes internal state, which makes validation possible
  • Grouping classes into packages such as game and boards organises the engine by concept
  • Package boundaries force access through getters, enforcing encapsulation