좋아, 물건이 점점 커지고 다음과 같은 열 가지 클래스로 끝났습니다.
이 방법의 결론은 모든 커뮤니케이션이 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 이외의 참가자를위한 어댑터입니까?