codecamp

命令模式详解:如何在手游后端架构中实现请求封装和操作管理

Hello,大家好,我是 V 哥

命令模式(Command Pattern)

命令模式是一种行为设计模式,它将一个请求封装为一个对象,从而允许用户使用不同的请求、队列或日志请求来参数化其他对象。命令模式也支持可撤销的操作。

在手游后端架构中的应用

  1. 封装玩家操作请求
    命令模式可以将玩家的操作请求(如移动、攻击、技能释放等)封装成对象,这些对象可以被存储在队列中,以便按顺序处理。

  1. 分离发送者和接收者
    通过命令模式,可以将发起操作的对象(发送者)和执行操作的对象(接收者)分离,使得系统更加模块化,易于扩展和维护。

  1. 实现操作的撤销和重做
    在游戏中,玩家可能会犯错或需要撤销之前的行动。命令模式可以轻松实现操作的撤销和重做功能。

  1. 异步执行操作
    命令模式可以将操作封装为对象,这些对象可以异步执行,不会阻塞主线程,提高游戏的响应性和性能。

  1. 广播玩家行为
    在游戏中,一个玩家的行为可能会影响其他玩家或游戏环境。命令模式可以将这些行为封装为命令对象,并通过事件系统广播给所有受影响的实体。

  1. 管理协同操作
    在多人游戏中,命令模式可以管理玩家之间的协同操作,确保操作的一致性和顺序性。

  1. 管理资源分配和回收
    游戏中的资源(如金币、道具等)的分配和回收可以通过命令模式来管理,确保资源操作的原子性和一致性。

  1. 封装网络请求和响应
    在网络游戏中,命令模式可以用于封装网络请求和响应,简化网络通信逻辑。

命令模式与其他设计模式的结合

命令模式通常与其他设计模式结合使用,如策略模式、观察者模式、状态模式等,以构建一个灵活、可扩展和易于维护的系统。

案例演示

创建一个完整的手游后端服务端示例涉及到许多组件,包括网络通信、数据库交互、业务逻辑处理等。在这里,我将提供一个非常简化的示例,它模拟了一个基本的游戏后端服务,包括玩家注册、登录和获取玩家信息的功能。这个示例将使用Java的Socket编程来处理客户端请求。

注意:这个示例仅用于教学目的,实际的手游后端会更加复杂,需要考虑安全性、并发性、数据库存储、错误处理等多个方面。

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);
        }


        // 关闭连接
        client.close();
    }
}

以上是本文的全部内容笔记,感谢老铁们的支持和鼓励,不当之处还请不吝赐教,欢迎关注威哥爱编程,努力的人相信总会有回报。

读写锁分离设计模式:提升商城系统库存管理性能的利器
20种单例模式实现与变异总结 - 单例模式全面解析
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }