3

作成中の MMORPG のソケット サーバーで作業していますが、読みやすくするためにコマンドとハンドラーを整理する方法がわかりません。

ban、kick、identify などのコマンドを data[0] から取得します。HashMap を使用して Interface Command を使用し、Command を実装する各ハンドラ/コマンドの新しいクラスを作成できることを読みました。 . 次に、HashMap を作成し、そこから移動します。また、あなたが反省できることも読みました。経験豊富なプログラマーがするようなことをしたい。

クライアントクラス:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client implements Runnable {

    private Socket socket;
    private Server server;
    private boolean isConnected;
    private BufferedReader in;
    private PrintWriter out;

    public Client(Socket socket, Server server) {
        this.socket = socket;
        this.server = server;
        this.isConnected = true;
        this.in = null;
        this.out = null;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            while (isConnected) {
                String recv = in.readLine().trim();

                if (recv != null) {
                    String[] data = recv.split("%");
                }
            }
        } catch (IOException e) {}
    }

    public synchronized void send(String data) {
        out.println(data);
    }
}
4

1 に答える 1

2

あなたが望むのは、Command Patternを使用することです。

クライアントからのコマンドを処理するためにコマンド パターンを使用する方法を次に示します。

/* Command Exception. */
public class ClientCommandException extends Exception {
    public ClientCommandException(String msg) {
        super(msg);
    }
}

/* The ClientCommand interface */
public interface ClientCommand {
    void execute(Client client, String[] params) throws ClientCommandException;
}

import java.util.HashMap;
import java.util.Arrays;

/* Container for commands */
public class Commands implements ClientCommand {
    private HashMap<String, ClientCommand> cmds;

    public Commands() {
        cmds = new HashMap<String, ClientCommand>();
    }

    public void addCommand(ClientCommand cmd, String name) {
        cmds.put(name, cmd);
    }

    public void execute(Client client, String[] params) throws ClientCommandException {
        ClientCommand cmd = cmds.get(params[0]);
        if(cmd != null) {
            cmd.execute(client, Arrays.copyOfRange(params, 1, params.length));
        } else {
            throw new ClientCommandException("Unknown Command: " + params[0]);
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Client implements Runnable {

    private boolean isConnected;
    private Commands cmds;
    private BufferedReader in;
    private PrintWriter out;

    private class EchoCommand implements ClientCommand {
        public void execute(Client client, String[] params) throws ClientCommandException {
            StringBuilder b = new StringBuilder("Echo back:");
            int len = params.length;
            for(int i = 0; i < len; i++) {
                b.append(' ');
                b.append(params[i]);
            }
            client.send(b.toString());
        }
    }

    private class DisconnectCommand implements ClientCommand {
        public void execute(Client client, String[] params) throws ClientCommandException {
            client.close();
        }
    }

    public Client() {
        cmds = new Commands();
        cmds.addCommand(new EchoCommand(), "echo");
        cmds.addCommand(new DisconnectCommand(), "disconnect");
        /* sub-commands */
        Commands server = new Commands();
        server.addCommand(new EchoCommand(), "print");
        cmds.addCommand(server, "server");
        isConnected = true;
    }

    public void addCommand(ClientCommand cmd, String name) {
        cmds.addCommand(cmd, name);
    }

    public void close() {
        isConnected = false;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out, true);

            while (isConnected) {
                String recv = in.readLine().trim();

                if (recv != null) {
                    String[] data = recv.split("%");
                    try {
                        cmds.execute(this, data);
                    } catch(ClientCommandException e) {
                        /* Return some error back to the client. */
                        out.println(e.toString());
                    }
                }
            }
        } catch (IOException e) {}
    }

    public synchronized void send(String data) {
        out.println(data);
    }

    public static void main(String[] args){
        Client client = new Client();
        System.out.println("Start Client.");
        client.run();
    }
}
于 2013-05-27T01:21:17.327 に答える