好的,事情逐渐升级了,我结束了以下十节课...
此方法的底线是,所有通信都使用Message
类进行,即游戏从不直接调用玩家的方法,而始终使用框架中的通信器类。对于本机Java类,有一个基于反射的通信器,然后对于所有非Java播放器,必须有一个自定义通信器。Message<Integer> message = new Message<>("say", Integer.class, "Hello");
会初始化一条消息,该消息将返回到say
带有参数的,名为的方法。然后将其传递到通信器(使用播放器类型使用工厂生成的通信器),然后执行该命令。"Hello"
Integer
import java.util.Optional;
public class Game {
Player player; // In reality you'd have a list here
public Game() {
System.out.println("Game starts");
player = new PlayerOne();
}
public void play() {
Message<Boolean> message1 = new Message<>("x", Boolean.class, true, false, true);
Message<Integer> message2 = new Message<>("y", Integer.class, "Hello");
Result result1 = sendMessage(player, message1);
System.out.println("Response 1: " + result1.getResult());
Result result2 = sendMessage(player, message2);
System.out.println("Response 2: " + result2.getResult());
}
private Result sendMessage(Player player, Message<?> message1) {
return Optional.ofNullable(player)
.map(Game::createCommunicator)
.map(comm -> comm.executeCommand(message1))
.get();
}
public static void main(String[] args) {
Game game = new Game();
game.play();
}
private static PlayerCommunicator createCommunicator(Player player) {
if (player instanceof NativePlayer) {
return new NativePlayerCommunicator((NativePlayer) player);
}
return new ExternalPlayerCommunicator((ExternalPlayer) player);
}
}
public abstract class Player {}
public class ExternalPlayer extends Player {}
public abstract class NativePlayer extends Player {
abstract boolean x(Boolean a, Boolean b, Boolean c);
abstract Integer y(String yParam);
abstract Void z(Void zParam);
}
public abstract class PlayerCommunicator {
public abstract Result executeCommand(Message message);
}
import java.lang.reflect.Method;
public class NativePlayerCommunicator extends PlayerCommunicator {
private NativePlayer player;
public NativePlayerCommunicator(NativePlayer player) { this.player = player; }
public Result executeCommand(Message message) {
try {
Method method = player.getClass().getDeclaredMethod(message.getMethod(), message.getParamTypes());
return new Result(method.invoke(player, message.getArguments()));
} catch (Exception e) { throw new RuntimeException(e); }
}
}
public class ExternalPlayerCommunicator extends PlayerCommunicator {
private ExternalPlayer player;
public ExternalPlayerCommunicator(ExternalPlayer player) { this.player = player; }
@Override
public Result executeCommand(Message message) { /* Do some IO stuff */ return null; }
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Message<OUT> {
private final String method;
private final Class<OUT> returnType;
private final Object[] arguments;
public Message(final String method, final Class<OUT> returnType, final Object... arguments) {
this.method = method;
this.returnType = returnType;
this.arguments = arguments;
}
public String getMethod() { return method; }
public Class<OUT> getReturnType() { return returnType; }
public Object[] getArguments() { return arguments; }
public Class[] getParamTypes() {
List<Class> classes = Arrays.stream(arguments).map(Object::getClass).collect(Collectors.toList());
Class[] classArray = Arrays.copyOf(classes.toArray(), classes.size(), Class[].class);
return classArray;
}
}
public class PlayerOne extends NativePlayer {
@Override
boolean x(Boolean a, Boolean b, Boolean c) {
System.out.println(String.format("x called: %b %b %b", a, b, c));
return a || b || c;
}
@Override
Integer y(String yParam) {
System.out.println("y called: " + yParam);
return yParam.length();
}
@Override
Void z(Void zParam) {
System.out.println("z called");
return null;
}
}
public class Result {
private final Object result;
public Result(Object result) { this.result = result; }
public Object getResult() { return result; }
}
(PS。在我看来,我现在还不能完全将其提炼为其他有用的关键字:Command Pattern,Visitor Pattern,java.lang.reflect.ParameterizedType)
PlayerComm extends Player
”部分感到困惑。所有Java参与者都在扩展Player
,并且此类PlayerComm
是非Java参与者的适配器吗?