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

2024-12-31 09:39 更新

Hello,大家好,我是 V 哥

命令模式(Command Pattern)

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

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

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

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

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

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

  1. 廣播玩家行為
    在游戲中,一個(gè)玩家的行為可能會影響其他玩家或游戲環(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)建一個(gè)靈活、可擴(kuò)展和易于維護(hù)的系統(tǒng)。

案例演示

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

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

Player類

public class Player {
    private String id;
    private String username;
    private String password;


    public Player(String id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }


    // Getters and setters
    public String getId() {
        return id;
    }


    public String getUsername() {
        return username;
    }


    public String getPassword() {
        return password;
    }
}

PlayerService類

import java.util.HashMap;
import java.util.Map;


public class PlayerService {
    private Map<String, Player> players = new HashMap<>();


    public synchronized String registerPlayer(String username, String password) {
        String playerId = Integer.toString(players.size() + 1);
        players.put(playerId, new Player(playerId, username, password));
        return playerId;
    }


    public synchronized Player login(String username, String password) {
        for (Player player : players.values()) {
            if (player.getUsername().equals(username) && player.getPassword().equals(password)) {
                return player;
            }
        }
        return null;
    }


    public synchronized Player getPlayer(String playerId) {
        return players.get(playerId);
    }
}

GameServer類

import java.io.*;
import java.net.*;
import java.util.Scanner;


public class GameServer {
    private ServerSocket serverSocket;
    private final int PORT = 12345;
    private PlayerService playerService = new PlayerService();


    public void startServer() {
        try {
            serverSocket = new ServerSocket(PORT);
            System.out.println("Game server is running on port " + PORT);


            while (true) {
                Socket socket = serverSocket.accept();
                new Handler(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private class Handler extends Thread {
        private Socket socket;
        private BufferedReader in;
        private PrintWriter out;


        public Handler(Socket socket) {
            this.socket = socket;
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        public void run() {
            try {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println("Received: " + inputLine);
                    if ("REGISTER".equals(inputLine)) {
                        String playerId = playerService.registerPlayer("username", "password");
                        out.println("REGISTERED " + playerId);
                    } else if ("LOGIN".equals(inputLine)) {
                        Player player = playerService.login("username", "password");
                        if (player != null) {
                            out.println("LOGIN_SUCCESS " + player.getId());
                        } else {
                            out.println("LOGIN_FAILURE");
                        }
                    } else if ("GET_PLAYER".equals(inputLine)) {
                        String[] parts = inputLine.split(" ", 2);
                        if (parts.length == 2) {
                            Player player = playerService.getPlayer(parts[1]);
                            if (player != null) {
                                out.println("PLAYER " + player.getId() + " " + player.getUsername());
                            } else {
                                out.println("PLAYER_NOT_FOUND");
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void main(String[] args) {
        GameServer server = new GameServer();
        server.startServer();
    }
}

GameClient類

import java.io.*;
import java.net.Socket;


public class GameClient {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;


    public GameClient(String serverAddress, int port) {
        try {
            socket = new Socket(serverAddress, port);
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void sendCommand(String command) {
        out.println(command);
    }


    public String readResponse() {
        try {
            return in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    public void close() {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        GameClient client = new GameClient("localhost", 12345);


        // 注冊玩家
        client.sendCommand("REGISTER");
        String registerResponse = client.readResponse();
        System.out.println("Register response: " + registerResponse);


        // 登錄玩家
        client.sendCommand("LOGIN");
        String loginResponse = client.readResponse();
        System.out.println("Login response: " + loginResponse);


        // 獲取玩家信息
        String[] loginParts = loginResponse.split(" ", 2);
        if (loginParts.length == 2 && "LOGIN_SUCCESS".equals(loginParts[0])) {
            client.sendCommand("GET_PLAYER " + loginParts[1]);
            String playerResponse = client.readResponse();
            System.out.println("Player info response: " + playerResponse);
        }


        // 關(guān)閉連接
        client.close();
    }
}

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號