命令模式詳解:如何在手游后端架構(gòu)中實(shí)現(xiàn)請求封裝和操作管理

2024-12-31 09:39 更新

Hello,大家好,我是 V 哥

命令模式(Command Pattern)

命令模式是一種行為設(shè)計(jì)模式,它將一個請求封裝為一個對象,從而允許用戶使用不同的請求、隊(duì)列或日志請求來參數(shù)化其他對象。命令模式也支持可撤銷的操作。

在手游后端架構(gòu)中的應(yīng)用

  1. 封裝玩家操作請求
    命令模式可以將玩家的操作請求(如移動、攻擊、技能釋放等)封裝成對象,這些對象可以被存儲在隊(duì)列中,以便按順序處理。

  1. 分離發(fā)送者和接收者
    通過命令模式,可以將發(fā)起操作的對象(發(fā)送者)和執(zhí)行操作的對象(接收者)分離,使得系統(tǒng)更加模塊化,易于擴(kuò)展和維護(hù)。

  1. 實(shí)現(xiàn)操作的撤銷和重做
    在游戲中,玩家可能會犯錯或需要撤銷之前的行動。命令模式可以輕松實(shí)現(xiàn)操作的撤銷和重做功能。

  1. 異步執(zhí)行操作
    命令模式可以將操作封裝為對象,這些對象可以異步執(zhí)行,不會阻塞主線程,提高游戲的響應(yīng)性和性能。

  1. 廣播玩家行為
    在游戲中,一個玩家的行為可能會影響其他玩家或游戲環(huán)境。命令模式可以將這些行為封裝為命令對象,并通過事件系統(tǒng)廣播給所有受影響的實(shí)體。

  1. 管理協(xié)同操作
    在多人游戲中,命令模式可以管理玩家之間的協(xié)同操作,確保操作的一致性和順序性。

  1. 管理資源分配和回收
    游戲中的資源(如金幣、道具等)的分配和回收可以通過命令模式來管理,確保資源操作的原子性和一致性。

  1. 封裝網(wǎng)絡(luò)請求和響應(yīng)
    在網(wǎng)絡(luò)游戲中,命令模式可以用于封裝網(wǎng)絡(luò)請求和響應(yīng),簡化網(wǎng)絡(luò)通信邏輯。

命令模式與其他設(shè)計(jì)模式的結(jié)合

命令模式通常與其他設(shè)計(jì)模式結(jié)合使用,如策略模式、觀察者模式、狀態(tài)模式等,以構(gòu)建一個靈活、可擴(kuò)展和易于維護(hù)的系統(tǒng)。

案例演示

創(chuàng)建一個完整的手游后端服務(wù)端示例涉及到許多組件,包括網(wǎng)絡(luò)通信、數(shù)據(jù)庫交互、業(yè)務(wù)邏輯處理等。在這里,我將提供一個非常簡化的示例,它模擬了一個基本的游戲后端服務(wù),包括玩家注冊、登錄和獲取玩家信息的功能。這個示例將使用Java的Socket編程來處理客戶端請求。

注意:這個示例僅用于教學(xué)目的,實(shí)際的手游后端會更加復(fù)雜,需要考慮安全性、并發(fā)性、數(shù)據(jù)庫存儲、錯誤處理等多個方面。

Player類

  1. public class Player {
  2. private String id;
  3. private String username;
  4. private String password;
  5. public Player(String id, String username, String password) {
  6. this.id = id;
  7. this.username = username;
  8. this.password = password;
  9. }
  10. // Getters and setters
  11. public String getId() {
  12. return id;
  13. }
  14. public String getUsername() {
  15. return username;
  16. }
  17. public String getPassword() {
  18. return password;
  19. }
  20. }

PlayerService類

  1. import java.util.HashMap;
  2. import java.util.Map;
  3. public class PlayerService {
  4. private Map<String, Player> players = new HashMap<>();
  5. public synchronized String registerPlayer(String username, String password) {
  6. String playerId = Integer.toString(players.size() + 1);
  7. players.put(playerId, new Player(playerId, username, password));
  8. return playerId;
  9. }
  10. public synchronized Player login(String username, String password) {
  11. for (Player player : players.values()) {
  12. if (player.getUsername().equals(username) && player.getPassword().equals(password)) {
  13. return player;
  14. }
  15. }
  16. return null;
  17. }
  18. public synchronized Player getPlayer(String playerId) {
  19. return players.get(playerId);
  20. }
  21. }

GameServer類

  1. import java.io.*;
  2. import java.net.*;
  3. import java.util.Scanner;
  4. public class GameServer {
  5. private ServerSocket serverSocket;
  6. private final int PORT = 12345;
  7. private PlayerService playerService = new PlayerService();
  8. public void startServer() {
  9. try {
  10. serverSocket = new ServerSocket(PORT);
  11. System.out.println("Game server is running on port " + PORT);
  12. while (true) {
  13. Socket socket = serverSocket.accept();
  14. new Handler(socket).start();
  15. }
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. private class Handler extends Thread {
  21. private Socket socket;
  22. private BufferedReader in;
  23. private PrintWriter out;
  24. public Handler(Socket socket) {
  25. this.socket = socket;
  26. try {
  27. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  28. out = new PrintWriter(socket.getOutputStream(), true);
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. public void run() {
  34. try {
  35. String inputLine;
  36. while ((inputLine = in.readLine()) != null) {
  37. System.out.println("Received: " + inputLine);
  38. if ("REGISTER".equals(inputLine)) {
  39. String playerId = playerService.registerPlayer("username", "password");
  40. out.println("REGISTERED " + playerId);
  41. } else if ("LOGIN".equals(inputLine)) {
  42. Player player = playerService.login("username", "password");
  43. if (player != null) {
  44. out.println("LOGIN_SUCCESS " + player.getId());
  45. } else {
  46. out.println("LOGIN_FAILURE");
  47. }
  48. } else if ("GET_PLAYER".equals(inputLine)) {
  49. String[] parts = inputLine.split(" ", 2);
  50. if (parts.length == 2) {
  51. Player player = playerService.getPlayer(parts[1]);
  52. if (player != null) {
  53. out.println("PLAYER " + player.getId() + " " + player.getUsername());
  54. } else {
  55. out.println("PLAYER_NOT_FOUND");
  56. }
  57. }
  58. }
  59. }
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. } finally {
  63. try {
  64. socket.close();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }
  71. public static void main(String[] args) {
  72. GameServer server = new GameServer();
  73. server.startServer();
  74. }
  75. }

GameClient類

  1. import java.io.*;
  2. import java.net.Socket;
  3. public class GameClient {
  4. private Socket socket;
  5. private PrintWriter out;
  6. private BufferedReader in;
  7. public GameClient(String serverAddress, int port) {
  8. try {
  9. socket = new Socket(serverAddress, port);
  10. out = new PrintWriter(socket.getOutputStream(), true);
  11. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  12. } catch (IOException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. public void sendCommand(String command) {
  17. out.println(command);
  18. }
  19. public String readResponse() {
  20. try {
  21. return in.readLine();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. return null;
  25. }
  26. }
  27. public void close() {
  28. try {
  29. socket.close();
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. public static void main(String[] args) {
  35. GameClient client = new GameClient("localhost", 12345);
  36. // 注冊玩家
  37. client.sendCommand("REGISTER");
  38. String registerResponse = client.readResponse();
  39. System.out.println("Register response: " + registerResponse);
  40. // 登錄玩家
  41. client.sendCommand("LOGIN");
  42. String loginResponse = client.readResponse();
  43. System.out.println("Login response: " + loginResponse);
  44. // 獲取玩家信息
  45. String[] loginParts = loginResponse.split(" ", 2);
  46. if (loginParts.length == 2 && "LOGIN_SUCCESS".equals(loginParts[0])) {
  47. client.sendCommand("GET_PLAYER " + loginParts[1]);
  48. String playerResponse = client.readResponse();
  49. System.out.println("Player info response: " + playerResponse);
  50. }
  51. // 關(guān)閉連接
  52. client.close();
  53. }
  54. }

以上是本文的全部內(nèi)容筆記,感謝老鐵們的支持和鼓勵,不當(dāng)之處還請不吝賜教,歡迎關(guān)注威哥愛編程,努力的人相信總會有回報。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號