Your UI layer shouldn’t contain business logic. Your business logic shouldn’t know how data is stored. Your data access layer shouldn’t format strings for display.
Compare:
public class TicTacToe
{
private readonly char[,] _board = new char[3, 3];
public void Play()
{
while (true)
{
// Display logic...
for (var r = 0; r < 3; r++)
Console.WriteLine($"{_board[r, 0]}{_board[r, 1]}{_board[r, 2]}");
// Input handling...
var row = int.Parse(Console.ReadLine() ?? "0");
var col = int.Parse(Console.ReadLine() ?? "0");
_board[row, col] = 'X';
// Game rules...
if (_board[0, 0] == _board[1, 1] && _board[1, 1] == _board[2, 2])
{
Console.WriteLine("Winner!");
break;
}
}
}
}
… to:
public class TicTacToe
{
private readonly Board _board = new();
private readonly Display _display = new();
private readonly InputHandler _inputHandler = new();
public void Play()
{
while (!_board.HasWinner())
{
display.Render(_board);
var move = _inputHandler.GetNextMove();
_board.MakeMove(move);
}
_display.ShowWinner(_board.GetWinner());
}
}
… where the game rules, display, and input handling are separate, e.g.,
switching from a console input to a GUI only touches InputHandler.
- Design Principles | Hello Interview Low Level Design. www.hellointerview.com . Accessed Sep 10, 2026.