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