帮助代码组织

Aid with code organization?

本文关键字:代码 帮助      更新时间:2023-10-16

我一直在为我的游戏编写服务器代码。它运行得非常好,但 90% 的函数都在 1 个类中。

通常我发现知道如何划分事物很容易。每个对象要么是一个类,要么每个对话框都是一个类,并为其子级处理逻辑。

在这种情况下,服务器收到请求,然后告诉其他玩家或处理并通知相应的玩家。

这是头文件:

    class ServerCore : public ServerHost, public NetEventListener,
        public ServerEventProvider
    {
        NetEventDecoder m_dec;
        NetEventEncoder m_enc;
        LoginManager m_login;
        ServerPlayerManager m_playerMan;
        ServerTableManager m_tableMan;
        void sendToTarget();
        void sendToAllActive();
        void sendToActiveNotTarget();
        void sendToTable(int tableNo);

    public:
        ServerCore();
        virtual void onConnect (Lacewing::Server::Client &client);
        virtual void onDisconnect (Lacewing::Server::Client &client);
        virtual void onError (Lacewing::Error &error);
        virtual void onReceive (Lacewing::Server::Client &client, char * data, int size);
        virtual void sendChatMessageC(const std::string& message,ChatAreaEnum area);
        virtual void requestTableC(int tableNo, int seatNo);
        virtual void playerRequestSitC(int tableNumber, int seatNumber);
        virtual void playerStoodUpC();
        virtual void hostGameC(const SpadesGameInfo& info);
        virtual void gameMessageC(SpadesCSMessageEnum message, const std::vector<int>& params);
        virtual void modifyListC(const std::string& player, GroupTypeEnum group, bool add);
        virtual void canceledHostingRequestC();
        virtual void sendInviteC(int tableNo, const std::string& player);
        virtual void loginResult(const std::string& name, ServerPlayer* player,
            const std::string& sessionID, bool success, bool newSession);
        virtual void readyToReceiveLobbyDataC();
        virtual void playerAbandonedGameC();
        virtual void watchTableC(int tableNo);
        virtual void gameCompleted(int tableId);
        virtual void playerWantsPlayAgainC();
        virtual ~ServerCore(void);
    };
}

我真的不知道我怎么能把它分解成更小的班级。它们执行的任务将传递给其他对象,例如身份验证和从数据库检索数据,但所有事件当前都在此 1 文件中处理。

网络事件解码器在从通过线路接收的字符串转换后调用相应的方法。

这样做效果很好,但游戏会变得更大,我想保持干净和模块化。

这种设计是个好主意吗?如果不是,在游戏服务器开发中通常使用什么类型的模式来保持更加面向对象?

谢谢

看看你的类,就会想到命令模式。实际上,以 C 结尾的方法看起来非常像命令。如果您有命令界面:

class Command {
  virtual void execute() = 0;
}

以及每个命令的单独子类,然后NetEventDecoder可以将收到的字符串解码为特定命令。

此外,每当您发现自己将相同的数据传递给多个方法时,这都暗示其中隐藏着一个类。例如,您可以将所有采用tableNumber的方法拉入Table类中。我也会摆脱Manager类并更直接地对关联进行建模。

例如:

// A game server contains players and tables
class GameServer {
  map<string, Player *> players;
  map<int, Table *> tables;
  Player *findPlayer(const string &name);
  Table *findTable(int tableNumber);
  ...
}
// A player can perform various actions
class Player {
  string name;
  bool requestSeat(Table *table);
  void standUp();
  ...
}
// A table maintains the status of seats
class Table {
  int tableNumber;
  bool requestSeat(int seatNumber);
  ...
}

上面的GameServer类只是对游戏进行建模,根本不处理网络。然后,NetEventDecoderServerCore可以协调以提供网络功能并在GameServer上调用命令。示例命令可能如下所示:

class PlayerStandUpCommand : public Command {
  GameServer *server;
  string playerName;
  void execute() {
    Player *player = server->findPlayer(playerName);
    player->standUp();
  }
}