This document discusses using frameworks and design patterns to build a game framework. It begins by explaining the template method pattern and how it can be used to create a template for a game algorithm that subclasses implement specific functionality for. It then discusses refactoring the game framework to use the strategy pattern instead of template method by defining a game strategy interface that specific game implementations like tic-tac-toe would implement. It describes using dependency injection with Spring to allow strategies to be injected into the game framework at runtime.
2. Agenda
From Problem to Patterns
Implementing a simple game
Template Method
Strategy
Dependency Injection
3. Dependency Injection
Template Method Pattern
Strategy Pattern
Spring Framework (video)
Article by Fowler
Inversion of Control Containers and the
Dependency Injection pattern
Reading
5. Why use Frameworks?
▪ Frameworks can increase productivity
– We can create our own framework
– We can use some third party framework
▪ Frameworks implement general functionality
– We use the framework to implement our business logic
6. Framework design
▪ Inheritance of framework classes
▪ Composition of framework classes
▪ Implementation of framework interfaces
▪ Dependency Injection
?Your
Domain Code
Framework
7. Let’s make a Game TicTacToe
Let’s make a Game Framework
What patterns can we use?
From Problem to Patterns
8. Patterns
▪ Template Method
– Template of an algorithm
– Based on class inheritance
▪ Strategy
– Composition of an strategy
– Based on interface inheritance
9. Template Method Pattern
Create a template for steps of an algorithm and let subclasses
extend to provide specific functionality
▪ We know the steps in an algorithm and the order
– We don’t know specific functionality
▪ How it works
– Create an abstract superclass that can be extended for the
specific functionality
– Superclass will call the abstract methods when needed
10. What is the game algorithm?
initialize
while more plays
make one turn
print winnner
void initializeGame();
boolean endOfGame();
void makePlay(int player);
void printWinner();
13. Interface for game algorithm
package is.ru.honn.game.framwork;
public interface Game
{
void setPlayersCount(int playerCount);
void initializeGame();
void makePlay(int player);
boolean endOfGame();
void printWinner();
void playOneGame();
}
14. package is.ru.honn.game.framwork;
public abstract class AbstractGame implements Game
{
protected int playersCount;
public void setPlayersCount(int playersCount)
{
this.playersCount = playersCount;
}
public abstract void initializeGame();
public abstract void makePlay(int player);
public abstract boolean endOfGame();
public abstract void printWinner();
public final void playOneGame()
{
initializeGame();
int j = 0;
while (!endOfGame())
{
makePlay(j);
j = (j + 1) % playersCount;
}
The Template
DEPENDENCY INJECTION
GAMES MUST DO THIS
15. public final void playOneGame()
{
initializeGame();
int j = 0;
while (!endOfGame())
{
makePlay(j);
j = (j + 1) % playersCount;
}
printWinner();
}
}
The Template
GAME LOOP
18. public class TicTacToeGame extends AbstractGame
{
private char[][] board;
private final int[][] MARK = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
private char currentPlayerMark;
public void initializeGame()
{
board = new char[3][3];
currentPlayerMark = 'X';
initializeBoard();
printBoard();
System.out.println("To play, enter the number");
System.out.println("123n456n789non the board.");
}
The TicTacToe Game
19. public void makePlay(int player)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Player " + currentPlayerMark + " move: ");
int mark = 0;
try
{
String s = br.readLine();
mark = Integer.valueOf(s);
}
catch (IOException e)
{
e.printStackTrace();
}
board[col(mark)][row(mark)] = currentPlayerMark;
changePlayer();
printBoard();
}
The TicTacToe Game
20. public boolean endOfGame()
{
return (checkRowsForWin() || checkColumnsForWin() || checkDiagonalsForWin());
}
public void printWinner()
{
changePlayer();
System.out.println("Winner is " + currentPlayerMark);
}
The TicTacToe Game
23. Create a template for the steps of an algorithm
and inject the specific functionality
▪ Implement an interface to provide specific functionality
▪ Algorithms can be selected on-the-fly at runtime depending on
conditions
▪ Similar as Template Method but uses interface inheritance
Strategy Pattern
24. Strategy Pattern
▪ How it works
▪ Create an interface to use in the generic algorithm
▪ Implementation of the interface provides the specific
functionality
▪ Framework class has reference to the interface an
▪ Setter method for the interface
29. The Specific Strategy
public class TicTacToeStrategy implements GameStrategy
{
private char[][] board;
private final int[][] MARK = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
private char currentPlayerMark;
protected int playersCount;
public void setPlayersCount(int playersCount)
{ this.playersCount = playersCount; }
public int getPlayersCount()
{ return playersCount; }
public void initializeGame()
{
board = new char[3][3];
currentPlayerMark = 'X';
initializeBoard();
printBoard();
System.out.println("To play, enter the number");
System.out.println("123n456n789non the board.");
}
30. The Context
package is.ru.honn.game.framwork;
public class GamePlay
{
protected int playersCount;
protected GameStrategy gameStrategy;
public void setGameStrategy(GameStrategy gameStrategy)
{ this.gameStrategy = gameStrategy; }
public final void playOneGame(int playersCount)
{
gameStrategy.initializeGame();
int j = 0;
while (!gameStrategy.endOfGame())
{
gameStrategy.makePlay(j);
j = (j + 1) % playersCount;
}
gameStrategy.printWinner();
}
}
DEPENDENCY INJECTION
31. The Assembler
package is.ru.honn.game.framwork;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class GameRunner
{
public static void main(String[] args)
{
ApplicationContext context= new
ClassPathXmlApplicationContext("/spring-config.xml");
GameStrategy game = (GameStrategy)context.getBean("game");
GamePlay play = new GamePlay();
play.setGameStrategy(game);
play.playOneGame(game.getPlayersCount());
}
}
DEPENDENCY INJECTION
32. Dependency Injection
Removes explicit dependence on specific application code by
injecting depending classes into the framework
▪ Objects and interfaces are injected into the classes that to
the work
▪ Two types of injection
▪ Setter injection: using set methods
▪ Constructor injection: using constructors