Last active
March 12, 2025 21:58
-
-
Save kenpower/1536b7eb2f2358af2bf6bd7254cdccbc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The evolution demonstrates: | |
Starting with a single strategy for a game action. | |
Expanding to multiple strategies executed together. | |
Refactoring into a subject-observer structure. | |
Adding dynamic management for an arbitrary number of observers. | |
Strategy (Step 1): A single game-related behavior (e.g., starting the game) is encapsulated and executed, making it interchangeable with other behaviors like pausing or exiting. | |
Observer (Step 4): Multiple game components (observers) are notified of the button press and react in their own way (e.g., starting the game, playing a sound, updating the score). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
// Abstract strategy interface | |
class ButtonPressHandler { | |
public: | |
virtual void handlePress() = 0; | |
virtual ~ButtonPressHandler() = default; | |
}; | |
// Context class that uses the strategy | |
class GameController { | |
private: | |
ButtonPressHandler* handler; | |
public: | |
void pressXButton() { | |
handler->handlePress(); // Delegate to the strategy | |
} | |
}; | |
// Concrete strategy | |
class ResetLevelHandler : public ButtonPressHandler { | |
public: | |
void handlePress() override { | |
std::cout << "Controller button pressed - Level Resett\n"; | |
} | |
void setHandler(ButtonPressHandler* h){ | |
handler=h; | |
} | |
}; | |
class UpdateScoreHandler : public ButtonPressHandler { | |
public: | |
void handlePress() override { | |
std::cout << "Controller button pressed - Score updated\n"; | |
} | |
}; | |
int main() { | |
ResetLevelHandler reseter; | |
UpdateScoreHandler updater; | |
Controller controller(); | |
controller.setHandler(&reseter) | |
controller.pressButton(); | |
Controller controller(&updater); | |
controller.pressXButton(); | |
// What if we wanted to call both strategies at same time???? | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
extend the Controller to hold multiple game-related strategies | |
(e.g., starting the game, playing a sound, and updating the score) | |
and execute all of them when the button is pressed. | |
*/ | |
#include <iostream> | |
#include <vector> | |
// Abstract strategy interface (unchanged) | |
class ButtonPressHandler { | |
public: | |
virtual void handlePress() = 0; | |
virtual ~ButtonPressHandler() = default; | |
}; | |
// Context class modified to hold multiple strategies | |
class GameController { | |
private: | |
std::vector<ButtonPressHandler*> handlers; | |
public: | |
void addHandler(ButtonPressHandler* h) { | |
handlers.push_back(h); | |
} | |
void pressXButton() { | |
for (auto h : handlers) { | |
h->handlePress(); // Execute all strategies | |
} | |
} | |
}; | |
// Concrete strategies | |
class StartGameHandler : public ButtonPressHandler { | |
public: | |
void handlePress() override { | |
std::cout << "Controller button pressed - Game started\n"; | |
} | |
}; | |
class PlaySoundHandler : public ButtonPressHandler { | |
public: | |
void handlePress() override { | |
std::cout << "Controller button pressed - Sound played\n"; | |
} | |
}; | |
class UpdateScoreHandler : public ButtonPressHandler { | |
public: | |
void handlePress() override { | |
std::cout << "Controller button pressed - Score updated\n"; | |
} | |
}; | |
// Usage | |
int main() { | |
StartGameHandler starter; | |
PlaySoundHandler sound; | |
UpdateScoreHandler score; | |
Controller controller; | |
controller.addHandler(&starter); | |
controller.addHandler(&sound); | |
controller.addHandler(&score); | |
controller.pressXButton(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
We'll refactor the code to use a Subject base class that manages observers (formerly strategies), | |
with Controller inheriting from it to notify all observers of a button press. | |
*/ | |
#include <iostream> | |
#include <vector> | |
// Observer interface (renamed from ButtonPressHandler) | |
class ButtonPressObserver { | |
public: | |
virtual void update() = 0; | |
virtual ~ButtonPress() = default; | |
}; | |
// Subject base class to manage observers | |
class Subject { | |
private: | |
std::vector<Observer*> observers; | |
public: | |
void addObserver(Observer* o) { | |
observers.push_back(o); | |
} | |
void notifyObservers() { | |
for (auto o : observers) { | |
o->update(); | |
} | |
} | |
}; | |
// Concrete subject | |
class Controller : public Subject { | |
public: | |
void pressXButton() { | |
std::cout << "Controller button pressed\n"; | |
notifyObservers(); // Notify all observers | |
} | |
}; | |
// Concrete observers (formerly strategies) | |
class StartGameHandler : public ButtonPressObserver { | |
public: | |
void update() override { | |
std::cout << " - Game started\n"; | |
} | |
}; | |
class PlaySoundHandler : public ButtonPressObserver { | |
public: | |
void update() override { | |
std::cout << " - Sound played\n"; | |
} | |
}; | |
class UpdateScoreHandler : public ButtonPressObserver { | |
public: | |
void update() override { | |
std::cout << " - Score updated\n"; | |
} | |
}; | |
// Usage | |
int main() { | |
StartGameHandler starter; | |
PlaySoundHandler sound; | |
UpdateScoreHandler score; | |
Controller controller; | |
controller.addObserver(&starter); | |
controller.addObserver(&sound); | |
controller.addObserver(&score); | |
controller.pressXButton(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <algorithm> | |
// Observer interface | |
class Observer { | |
public: | |
virtual void update() = 0; | |
virtual ~Observer() = default; | |
}; | |
// Subject base class with add/remove functionality | |
class Subject { | |
private: | |
std::vector<Observer*> observers; | |
public: | |
void addObserver(Observer* o) { | |
observers.push_back(o); | |
} | |
void removeObserver(Observer* o) { | |
observers.erase( | |
std::remove(observers.begin(), observers.end(), o), | |
observers.end() | |
); | |
} | |
void notifyObservers() { | |
for (auto o : observers) { | |
o->update(); | |
} | |
} | |
}; | |
// Concrete subject | |
class Controller : public Subject { | |
public: | |
void pressXButton() { | |
std::cout << "Controller button pressed\n"; | |
notifyObservers(); | |
} | |
}; | |
// Concrete observers | |
class StartGameHandler : public Observer { | |
public: | |
void update() override { | |
std::cout << " - Game started\n"; | |
} | |
}; | |
class PlaySoundHandler : public Observer { | |
public: | |
void update() override { | |
std::cout << " - Sound played\n"; | |
} | |
}; | |
class UpdateScoreHandler : public Observer { | |
public: | |
void update() override { | |
std::cout << " - Score updated\n"; | |
} | |
}; | |
// Usage | |
int main() { | |
StartGameHandler starter; | |
PlaySoundHandler sound; | |
UpdateScoreHandler score; | |
Controller controller; | |
// Add observers | |
controller.addObserver(&starter); | |
controller.addObserver(&sound); | |
controller.addObserver(&score); | |
controller.pressXButton(); | |
std::cout << "\nRemoving sound observer\n"; | |
controller.removeObserver(&sound); | |
controller.pressXButton(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment