首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单聊天室

简单聊天室
EN

Code Review用户
提问于 2017-09-17 05:23:40
回答 1查看 1.2K关注 0票数 3

我正在用Java编写这个简单的聊天室,我希望重构几件事情,比如下面的switch语句应该被多态替换,或者至少不依赖于另一个类枚举。

消息对象:

代码语言:javascript
复制
public class Message implements Serializable {
    public enum MessageTypes {PUBLIC_MESSAGE,PTIVATE_MASSAGE,USER_DUPLICATE,USER_LOGOUT,SERVER_LOGOUT,USERSLIST}; 
    private String dest;
    private String src;
    private String messageContent;
    private MessageTypes type;


    public Message(String source) {
        src = source; 
    }

    public Message(String source,String message) {
        this(source);
        messageContent = message;
        type = MessageTypes.PUBLIC_MESSAGE;
    }

    public Message(String source,String destination,String message) {
        this(source);
        messageContent = message;
        dest= destination;
        type = MessageTypes.PTIVATE_MASSAGE;
    }

    public String getDest() {
        return dest;
    }
    public String getSrc() {
        return src;
    }
    public String getMessageContent() {
        return messageContent;
    }
    public MessageTypes getType() {
        return type;
    }

    private void setType(MessageTypes typeToSet) {
        type = typeToSet;
    }
    public static Message getServerLogoutMessage() {
        Message logoutMessage = new Message("Server");
        logoutMessage.setType(MessageTypes.SERVER_LOGOUT);
        return logoutMessage;
    }
    public static Message getServerLogoutMessage(String src) {
        Message logoutMessage = new Message(src);
        logoutMessage.setType(MessageTypes.SERVER_LOGOUT);
        return logoutMessage;
    }
    public static Message getUserLogoutMessage(String source) {
        Message logoutMessage = new Message(source);
        logoutMessage.setType(MessageTypes.USER_LOGOUT);
        return logoutMessage;
    }

    public static Message getUsersListMessage(String source) {
        Message usersMessage = new Message(source);
        usersMessage.setType(MessageTypes.USERSLIST);
        return usersMessage;
    }
    public static Message getDuplicateMessage() {
        Message msg = new Message("Server");
        msg.setType(MessageTypes.USER_DUPLICATE);
        return msg;
    }
    @Override
    public String toString() {
        return "Source : " + getSrc() + "\n" + 
                "Dest : " + getDest() + "\n" +
                "Type : " + getType() + "\n" +
                "Content : " + getMessageContent() + "\n";
    }
}

函数在服务器类中:

代码语言:javascript
复制
public synchronized void handelMessage(Message msg) {
    ClientListenerWriterPair p;
    String src = msg.getSrc();
    String content = msg.getMessageContent();
    String toWrite;
    switch (msg.getType()) {
    case PTIVATE_MASSAGE:
        sendPrivateMessage(msg);
        break;
    case PUBLIC_MESSAGE:
        toWrite = String.format("%s : %s",src,content);
        control.writeTextToGui(toWrite);
        spreadTheMessage(msg);
        break;
    case USER_LOGOUT:
        p = nameToClientHash.remove(msg.getSrc());
        p.getListener().close();
        p.getWriter().close();
        p.getWriter().setMsg(Message.getUserLogoutMessage("Server"));
        try {
            p.getWriter().join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        p.close();
        break;
    case SERVER_LOGOUT:
        p = nameToClientHash.remove(msg.getSrc());
        p.getListener().close();
        p.close();
        break;
    case USERSLIST:
        p = nameToClientHash.get(msg.getSrc());
        final Set<String> userSet = nameToClientHash.keySet();
        break;
    }
}
EN

回答 1

Code Review用户

发布于 2017-09-17 09:49:11

处理消息

...我希望重构几件事情,比如下面的switch语句应该被多态替换,或者至少不依赖其他类枚举。

您可以创建MessageHandler类来实现当前case语句中的操作,并将它们注册到具有Map<MessageType, MessageHandler>MessageHandlerRegistry中。然后,在处理传入的Message实例时,可以从MessageHandlerRegistry获取MessageHandler以执行适当的操作。与…有关的东西:

代码语言:javascript
复制
  interface MessageHandler {
    void handle();
  }

  interface MessageHandlerRegistry {
    void register(MessageType type, MessageHandler handler);

    MessageHandler get(MessageType type);
  }

  // ...

  void processMessage(Message message) {
    messageHandlerRegistry.get(message.type()).handle();
  }

创建Message实例

Message中,有几个创建消息的static方法,例如:

公共静态消息getServerLogoutMessage() {消息logoutMessage =新消息(“服务器”);logoutMessage返回logoutMessage;}

与其命名这些getSomething,不如将它们命名为newSomething,以指示新的实例创建。

但更大的问题是,创建Message实例有点繁琐,因为setType调用迫使您编写每种消息类型3行。

最好使用构建器模式,这样您就可以像这样更流畅地创建消息:

代码语言:javascript
复制
public static Message newServerLogoutMessage() {
    return builder().source("Server").type(MessageType.SERVER_LOGOUT).build();
}

实际上,我将保持Message类不受所有这些东西的影响,并将这些帮助工厂方法移动到一个Messages类中,这是一个常见的模式,例如在JDK的Collections类中。

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

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

复制
相关文章

相似问题

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