-
Notifications
You must be signed in to change notification settings - Fork 0
Singleton Template Method
Folder: 08-singleton-template-method
Intent. Guarantee a class has one instance and give the program a single point of access to it.
How this code does it. singleton.cpp builds a Logger as a Meyers singleton. getInstance holds a static Logger instance local variable and returns a reference to it. The static is constructed the first time the function runs and lives until the program ends, so there is exactly one logger. The constructor and destructor are private, and the copy constructor and copy assignment are deleted, which blocks any second instance. The logger's one job is report, which appends a line to log.txt. Two free functions, functionA and functionB, both write through Logger::getInstance, so they share the same file handle.
classDiagram
class Logger {
-ofstream ofs
-Logger()
-~Logger()
+getInstance() Logger&$
+report(string) void
+Logger(const Logger&) deleted
+operator=(const Logger&) deleted
}
Logger ..> Logger : getInstance() returns the one static instance
Intent. Define the skeleton of an algorithm in a base class and let subclasses fill in specific steps without changing the overall shape.
How this code does it. templateMethodGames.cpp has a Game base class. Its playGame is the template method: it initializes, loops through player moves until the game ends, then prints the winner. That order is fixed. The steps it calls, initializeGame, makeMove, and printWinner, are pure virtual primitive operations, and endOfGame is a hook with a default. Monopoly, Chess, and RockPaperScissors each subclass Game and supply those steps. RockPaperScissors is the one I added: it reads the human's choice, picks the computer's at random, and decides the round, all inside the move and winner steps while playGame stays untouched.
classDiagram
class Game {
#int playersCount_
#int movesCount_
#int playerWon_
+playGame(int) void
#initializeGame()* void
#makeMove(int)* void
#printWinner()* void
#endOfGame() bool
}
class Monopoly {
+initializeGame() void
+makeMove(int) void
+printWinner() void
}
class Chess {
+initializeGame() void
+makeMove(int) void
+printWinner() void
}
class RockPaperScissors {
+initializeGame() void
+makeMove(int) void
+printWinner() void
}
Game <|-- Monopoly
Game <|-- Chess
Game <|-- RockPaperScissors
g++ -std=c++17 08-singleton-template-method/singleton.cpp -o logger
./logger # writes to log.txt
g++ -std=c++17 08-singleton-template-method/templateMethodGames.cpp -o games
./games # plays chess and monopoly, then prompts for rock-paper-scissorsThe Game framework and the Monopoly and Chess subclasses came from the course. The Logger singleton and the RockPaperScissors subclass are mine.
Data structures & STL
Design patterns