Key Points
Fixed Component Slots:
class Entity {
TransformComponent* transform; // Always same slots
RenderComponent* render;
HealthComponent* health;
| #include <iostream> | |
| #include <string> | |
| // The Data Container (Anemic Property) | |
| class BankAccount { | |
| public: | |
| std::string id; | |
| double balance; | |
| bool isFrozen; |
Key Points
Fixed Component Slots:
class Entity {
TransformComponent* transform; // Always same slots
RenderComponent* render;
HealthComponent* health;
| #include <iostream> | |
| #include <vector> | |
| #include <string> | |
| // Interface - defines what all enemies must do | |
| class IEnemy { | |
| public: | |
| virtual ~IEnemy() {} // Virtual destructor for cleanup | |
| virtual void takeDamage(int damage) = 0; // Pure virtual = must implement |
| #include <iostream> | |
| #include <vector> | |
| #include <string> | |
| // Interface - defines what all enemies must do | |
| class IEnemy { | |
| public: | |
| virtual ~IEnemy() {} // Virtual destructor for cleanup | |
| virtual void takeDamage(int damage) = 0; // Pure virtual = must implement |
| #!/bin/bash | |
| # ================================================================ | |
| # setup-dotfiles.sh — public bootstrap script for dotfiles | |
| # Parameterised: GITHUB_TOKEN, GITHUB_USER, REPO_NAME | |
| # ================================================================ | |
| set -euo pipefail | |
| # ─── READ PARAMETERS OR ENV VARS ─────────────────────────────────────────── | |
| for arg in "$@"; do |
| #include <SFML/Graphics.hpp> | |
| #include <vector> | |
| // --- helper functions -------------------------------------------------------- | |
| void handlePlayerInput(sf::Sprite& player) | |
| { | |
| const float speed = 5.f; | |
| if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) | |
| player.move(-speed, 0); |
| // Code smell: Long method that does too many things | |
| #include <SFML/Graphics.hpp> | |
| void updateGameWorld(sf::RenderWindow& window, | |
| sf::Sprite& player, | |
| std::vector<sf::Sprite>& enemies, | |
| sf::Texture& explosionTex) | |
| { | |
| // 1. Process player input | |
| if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) |
| 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). |
The code demonstrates a game system refactored to use the Observer pattern, consisting of these key components:
Observer Interface (GameObserver): Defines methods for different game events (player damaged, player death, enemy death).
Subject Interface (Subject): Manages a list of observers and provides methods to add, remove, and notify observers.
Game Entities (Player and Enemy): Inherit from Subject and notify observers when their state changes.
| #include <iostream> | |
| #include <string> | |
| // Logger Interface | |
| class Logger { | |
| public: | |
| virtual void log(const std::string& message) = 0; | |
| virtual ~Logger() {} | |
| }; |