Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 内部非静态类。正确的方法?网袋_Java_Class_Websocket - Fatal编程技术网

Java 内部非静态类。正确的方法?网袋

Java 内部非静态类。正确的方法?网袋,java,class,websocket,Java,Class,Websocket,提示这样一个决定的正确性 我在Java(服务器)上有一个web套接字的连接点。它实现了onOpen、onMessage、onClose和onError方法 这是关于onMessage方法的 我不想在这个方法中塞满一个开关,这个开关对于所有可能的消息来说都是巨大的 我做了这种事情(我使用了一个内部非静态类来处理消息) @ServerEndpoint(value=“/endpoint”,configurator=SocketConfigurator.class,encoders=WsEncoder.

提示这样一个决定的正确性

我在Java(服务器)上有一个web套接字的连接点。它实现了
onOpen
onMessage
onClose
onError
方法

这是关于
onMessage
方法的

我不想在这个方法中塞满一个开关,这个开关对于所有可能的消息来说都是巨大的

我做了这种事情(我使用了一个内部非静态类来处理消息)

@ServerEndpoint(value=“/endpoint”,configurator=SocketConfigurator.class,encoders=WsEncoder.class,decoders=WsDecoder.class)
公共类WsEndpoint{
私有静态最终CopyOnWriteArrayList wsWebUsers=新CopyOnWriteArrayList();
公共WsEndpoint(){
LOGGER.info(“创建的端点”);
}
@奥诺彭
公共开放(会议){
LOGGER.info(“端点打开”);
}
@OnMessage
public void onMessage(会话会话,WsMessage WsMessage){
新的WsOnMessage(会话,wsMessage);
}
@一次
公共void onClose(会话){
}
@一个错误
公共作废确认人(会话,可丢弃的ex){
记录器错误(“端点错误”,ex);
}
私有类WsOnMessage{
非公开会议;
私有消息;
WsOnMessage(会话会话,WsMessage WsMessage){
this.session=会话;
this.wsMessage=wsMessage;
执行();
}
私有void execute(){
开关(wsMessage.getType()){
违约:
LOGGER.info(“端点未知消息”);
打破
}
}
}
}
这样做是真的吗?有没有更优雅的方式来处理信息


谢谢。

创建一个抽象类,
execute
方法被其子类覆盖:

public abstract class Command {
  protected final Session session;
  protected final WsMessage message;

  public Command(Session session, WsMessage message) {
    this.session = session;
    this.message = message;
}


  public abstract void execute();
}
创建知道如何将
WsMessage
映射到相应的
命令
类的命令工厂:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class CommandFactory {
  private <T extends Command> Class<T> findCommandClass(WsMessage message) {
    // switch on message, or lookup in a Map<WsMessage,Class<? extends Command>>, or,...
    // throw exception if no registered class
    throw new RuntimeException(String.format("No known command for message %s", message));
}

  private <T extends Command> T createInstance(Class<T> clazz, Session session, WsMessage message) {
    try {
        Constructor<T> constructor = clazz.getConstructor(Session.class, WsMessage.class);
        return constructor.newInstance(session, message);
    } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(String.format("Could not instantiate  %s", clazz), e);
    }
  }

public Command createCommand(Session session, WsMessage message) {
    Class<Command> commandClass = findCommandClass(message);
    return createInstance(commandClass, session, message);
}
}
此模式将允许您通过模拟命令工厂进行测试

一些想法:

  • 使CommandFactory抽象,并使用引发异常的默认实现保护find方法
  • 可能只将
    会话
    作为execute的参数传递,而不是传递给工厂

我会使用工厂和命令模式。@M.leRutte您能粘贴示例吗?请告诉我。如何访问连接到我的websocket的我的用户列表?这个列表是静态的,线程安全的,我不知道。我认为你问的是另一个问题。也许接受这个问题,然后提出一个新问题。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class CommandFactory {
  private <T extends Command> Class<T> findCommandClass(WsMessage message) {
    // switch on message, or lookup in a Map<WsMessage,Class<? extends Command>>, or,...
    // throw exception if no registered class
    throw new RuntimeException(String.format("No known command for message %s", message));
}

  private <T extends Command> T createInstance(Class<T> clazz, Session session, WsMessage message) {
    try {
        Constructor<T> constructor = clazz.getConstructor(Session.class, WsMessage.class);
        return constructor.newInstance(session, message);
    } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(String.format("Could not instantiate  %s", clazz), e);
    }
  }

public Command createCommand(Session session, WsMessage message) {
    Class<Command> commandClass = findCommandClass(message);
    return createInstance(commandClass, session, message);
}
}
public class WsEndpoint {
   private CommandFactory factory;

   // if you are required to have a no-arg default constructor and can't use dependency injection:
   public WsEndpoint() {
       this(new MyStandardCommandFactory()); // create an instance of the standard command factory.
   }

   public WsEndpoint(CommandFactory factory) {
       this.factory = Objects.requireNonNull(factory);
   }

   @OnMessage
   public void onMessage(Session session, WsMessage wsMessage) {
        Command command = factory.createCommand(session, wsMessage);
        command.execute();
   }