首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MUD客户端控制器

MUD客户端控制器
EN

Code Review用户
提问于 2013-09-04 10:02:59
回答 1查看 298关注 0票数 2

考虑到我的技能水平,我想确保我正确地使用了相关的模式,并遵循了命名约定。这是一个使用Apache 泥浆客户的穷人TelnetClient控制器。项目在GitHub上。

startReadPrintThreads通过实例化工作人员来启动线程,进而启动I/O线程。当接收到消息时,CharacterDataQueueWorker通知控制器,然后控制器将从ConcurrentLinkedQueue<Command>中添加sendMessages,这两个i/o线程都可以将其添加到其中。只有sendCommands才能从commandsQueue中弹出或删除Command

  1. 这是生产者-消费者,还是向后生产者消费模式?
  2. 是否遵循命名惯例?
  3. 是否有明显的错误或反模式?
代码语言:javascript
复制
package telnet;

import static java.lang.System.out;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.net.telnet.TelnetClient;

public final class Controller implements Runnable, Observer {

    private TelnetClient telnetClient = new TelnetClient();
    private InputStreamWorker remoteOutputWorker = new InputStreamWorker();
    private ConsoleReader localInputReader = new ConsoleReader();
    private CharacterDataQueueWorker remoteDataQueueWorker = new CharacterDataQueueWorker();
    private RemoteOutputRegexMessageWorker remoteMessageWorker = new RemoteOutputRegexMessageWorker();
    private final ConcurrentLinkedQueue<Character> remoteCharDataQueue = new ConcurrentLinkedQueue();
    private final ConcurrentLinkedQueue<Command> commandsQueue = new ConcurrentLinkedQueue();

    private Controller() {
    }

    public void startReadPrintThreads() throws SocketException, IOException {
        remoteOutputWorker.print(telnetClient.getInputStream(), remoteCharDataQueue);
        localInputReader.read();
        localInputReader.addObserver(this);
        remoteDataQueueWorker.read(remoteCharDataQueue);
        remoteDataQueueWorker.addObserver(this);
    }

    private void sendCommands() {
        String commandString = null;
        Iterator it = commandsQueue.iterator();
        byte[] commandBytes = null;
        OutputStream outputStream = telnetClient.getOutputStream();
        while (it.hasNext()) {
            try {
                commandBytes = commandsQueue.remove().getCommand().getBytes();
                outputStream.write(commandBytes);
                outputStream.write(10);
                outputStream.flush();
            } catch (IOException ex) {
                out.println("sendCommand\n" + ex);
            }
        }
    }

    @Override
    public void update(Observable o, Object arg) {

        if (o instanceof CharacterDataQueueWorker) {
            String remoteOutputMessage = remoteDataQueueWorker.getFinalData();
            remoteMessageWorker.parseWithRegex(remoteOutputMessage);
            sendCommands();
        }

        if (o instanceof ConsoleReader) {
            String commandString = localInputReader.getCommand();
            Command command = new Command(commandString);
            commandsQueue.add(command);
            sendCommands();
        }
    }

    @Override
    public void run() {
        try {
            Properties props = PropertiesReader.getProps();
            InetAddress host = InetAddress.getByName(props.getProperty("host"));
            int port = Integer.parseInt(props.getProperty("port"));
            telnetClient.connect(host, port);
            startReadPrintThreads();
        } catch (UnknownHostException ex) {
            out.println(ex);
        } catch (SocketException ex) {
            out.println(ex);
        } catch (IOException ex) {
            out.println(ex);
        }
    }

    public static void main(String[] args) throws SocketException, IOException {
        new Controller().run();
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2013-09-04 18:44:26

成员变量:您将其中两个变量定义为final,但从不为其中任何一个分配新值。最好把它们都做成final

sendCommands()

  • commandString从未被使用过。
  • commandBytes尽可能在最紧的范围内定义它。如果将其定义为try的第一行,则不必担心它是否为null或具有以前用法中的其他值。
  • 您使用的是it.hasNext(),但从未调用it.next()进行迭代,这似乎很奇怪。如果您只关心集合是否有任何剩余值,请使用!commandsQueue.isEmpty()。您要做的是取决于可能更改的实现细节。返回的迭代器可以是集合的快照,如果以后更改集合,则不会更改。

update()

我更喜欢有2个Observer实例,而不是必须检查传递给方法的Observable的类型。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/30784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档