[BlindSpot] Log 03. Let's follow the SOLID principles : SRP

Published: (January 27, 2026 at 06:23 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Overview

SOLID principles are the five design principles of object‑oriented programming.

  • SRP (Single Responsibility Principle) – a class (object) should have only one responsibility (function).
  • DIP (Dependency Inversion Principle) – higher‑level modules should depend on abstractions (interfaces) rather than on concrete implementations of lower‑level modules.

Refactoring Example

Before

// ServerPacketHandler is both receiving and processing packets.
void ServerPacketHandler::Handle_MAKE_ROOM_REQUEST(std::shared_ptr<Session> session,
                                                    blindspot::MakeRoomRequest& pkt) {
    if (session->room.lock()) {
        // Already in a room
        blindspot::MakeRoomResponse res;
        res.set_result(blindspot::MAKE_ALREADY_IN_ROOM);
        session->Send(blindspot::PacketID::ID_MAKE_ROOM_RESPONSE, res);
        return;
    }
    std::string title = pkt.room_name();
    int32_t maxPlayers = pkt.max_players();
    std::string password = pkt.password();
    // ...omission
}

After

// Delegates the work to a dedicated service, respecting SRP.
void ServerPacketHandler::Handle_JOIN_ROOM_REQUEST(std::shared_ptr<Session> session,
                                                   blindspot::JoinRoomRequest& pkt) {
    RoomService::JoinRoom(session, pkt);
}

Session and Player Separation

Player Model

// Models/Player.h
class Player {
public:
    int32_t id;
    std::string name;
    std::mutex _nameLock;
    std::weak_ptr<Room> room;

    void SetName(const std::string& playerName) {
        std::lock_guard<std::mutex> lock(_nameLock);
        name = playerName;
    }

    std::string GetName() {
        std::lock_guard<std::mutex> lock(_nameLock);
        return name;
    }
};

Session Model

// Network/Session.h
class Session : public std::enable_shared_from_this<Session> {
public:
    explicit Session(tcp::socket socket) : socket_(std::move(socket)) {}

    std::shared_ptr<Player> player_;
    std::string _sessionKey;
    // ... other communication‑related members
private:
    tcp::socket socket_;
};

Manager Classes Before Refactor

PlayerManager

// PlayerManager.h
class PlayerManager {
    static std::atomic<int32_t> playerIdGenerator_;
    static std::mutex name_mutex_;
    static std::map<int32_t, std::string> playerIdToName_;

public:
    static PlayerManager& Instance();
    int32_t GeneratePlayerId();
    void RegisterPlayerName(int32_t playerId, const std::string& name);
    void EditPlayerName(int32_t playerId, const std::string& newName);
    std::string GetPlayerNameById(int32_t playerId);
};

AuthManager

// AuthManager.h
class AuthManager {
    static std::mutex token_mutex_;
    static std::map<std::string, int32_t> sessionKeyToPlayerId_;
    static std::mutex name_mutex_;
    static std::map<int32_t, std::string> playerIdToName_;

public:
    static AuthManager& Instance();
    static int32_t GetPlayerIdBySessionKey(const std::string& token);
    static std::string GenerateSessionKey();
    static void RemoveSession(const std::string& token);
    static void RegisterSession(const std::string& token, int32_t playerId);
};

SessionManager

// SessionManager.h
class SessionManager {
    std::mutex sessions_mutex_;
    std::set<std::shared_ptr<Session>> sessions_;

public:
    static SessionManager& Instance();
    void Add(std::shared_ptr<Session> session);
    void Remove(std::shared_ptr<Session> session);
    void Broadcast(uint16_t id, google::protobuf::Message& msg);
};

Future Work

The current refactor aligns the code with SRP. The next step will be to apply the Dependency Inversion Principle (DIP), extracting abstractions for lower‑level modules (e.g., networking, storage) so that higher‑level services depend on interfaces rather than concrete implementations.

Back to Blog

Related posts

Read more »

SOLID & OOP Design business case

Are OOP design principles useful, or do they just add unnecessary complexity? OOP Design Principles Encapsulation Encapsulation means bundling data with the met...