Java 观察数据并根据数据值选择上下文策略
下面是一个非常基本的Java版本,它使用ApacheJava 观察数据并根据数据值选择上下文策略,java,oop,design-patterns,observer-pattern,strategy-pattern,Java,Oop,Design Patterns,Observer Pattern,Strategy Pattern,下面是一个非常基本的Java版本,它使用ApacheTelnetClient(而不是ssh) 主要作为练习,Context到目前为止只有一个策略,即TargetStrategy,它返回一个依赖于GameData对象值的Deque 我们的想法是增加更多的策略,更重要的是根据游戏数据选择策略。例如,在数据中传递字符串目标 然后我就有点迷路了。有一件事我很确定,没有游戏数据的上下文是没有意义的。例如,如果没有生物的名字,就不可能选择一个生物作为目标 当前的流程,设置策略,然后设置数据,是向后的。这是否
TelnetClient
(而不是ssh)
主要作为练习,Context
到目前为止只有一个策略,即TargetStrategy
,它返回一个依赖于GameData
对象值的Deque
我们的想法是增加更多的策略,更重要的是根据游戏数据选择策略。例如,在数据中传递字符串目标
然后我就有点迷路了。有一件事我很确定,没有游戏数据的上下文是没有意义的。例如,如果没有生物的名字,就不可能选择一个生物作为目标
当前的流程,设置策略,然后设置数据,是向后的。这是否需要StrategySelector
类型类,该类将游戏数据作为参数并返回上下文
上下文
代码:
package game;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.logging.Logger;
import model.GameAction;
import model.GameData;
public class Context {
private static Logger log = Logger.getLogger(Context.class.getName());
private Strategy strategy;
private GameData gameData = null;
private Context() {
}
public Context(Strategy strategy) {
this.strategy = strategy;
}
public Deque<GameAction> executeStrategy() {
log.info(strategy.toString());
return this.strategy.execute(gameData);
}
public void setGameData(GameData gameData) {
this.gameData = gameData;
}
}
打包游戏;
导入java.util.ArrayDeque;
导入java.util.Deque;
导入java.util.logging.Logger;
导入model.GameAction;
导入model.GameData;
公共类上下文{
私有静态记录器log=Logger.getLogger(Context.class.getName());
私人战略;
私有GameData GameData=null;
私有上下文(){
}
公共环境(战略){
这个。策略=策略;
}
公共部门执行策略(){
log.info(strategy.toString());
返回此.strategy.execute(gameData);
}
公共无效setGameData(GameData GameData){
this.gameData=gameData;
}
}
当观察到新的数据时,你会做什么?控制器代码如下:
package telnet;
import game.Context;
import game.TargetStrategy;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Deque;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
import java.util.logging.Logger;
import org.apache.commons.net.telnet.TelnetClient;
import model.GameAction;
import model.GameData;
import model.TelnetEventProcessor;
public class TelnetConnection implements Observer {
private static Logger log = Logger.getLogger(TelnetConnection.class.getName());
private TelnetClient telnetClient = new TelnetClient();
private InputOutput inputOutput = new InputOutput();
private TelnetEventProcessor parser = new TelnetEventProcessor();
private Context context;// = new LogicalContext();
public TelnetConnection() {
try {
init();
} catch (SocketException ex) {
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
}
private void init() throws SocketException, FileNotFoundException, IOException {
Properties props = PropertiesReader.getProps();
InetAddress host = InetAddress.getByName(props.getProperty("host"));
int port = Integer.parseInt(props.getProperty("port"));
telnetClient.connect(host, port);
inputOutput.readWriteParse(telnetClient.getInputStream(), telnetClient.getOutputStream());
inputOutput.addObserver(this);
parser.addObserver(this);
}
private void sendAction(GameAction action) throws IOException {
log.fine(action.toString());
byte[] actionBytes = action.getAction().getBytes();
OutputStream outputStream = telnetClient.getOutputStream();
outputStream.write(actionBytes);
outputStream.write(13);
outputStream.write(10);
outputStream.flush();
}
private void sendActions(Deque<GameAction> gameActions) {
while (!gameActions.isEmpty()) {
GameAction action = gameActions.remove();
try {
sendAction(action);
} catch (IOException ex) {
}
}
}
@Override
public void update(Observable o, Object arg) {
GameData data = null;
String line = null;
Deque<GameAction> gameActions;
if (o instanceof InputOutput) {
if (arg instanceof String) {
line = arg.toString();
parser.parse(line);
} else if (arg instanceof GameData) {
data = (GameData) arg;
context = new Context(new TargetStrategy());
context.setGameData(data); //data changes frequently!
//strategy depends on data
//put all this in another class?
gameActions = context.executeStrategy();
sendActions(gameActions);
} else {
log.info("not a i/o arg");
}
} else if (o instanceof TelnetEventProcessor) {
if (arg instanceof GameData) {
log.info("game data arg");
data = (GameData) arg;
gameActions = context.executeStrategy();
sendActions(gameActions);
} else {
log.info("not a telnetevent arg");
}
}
}
public static void main(String[] args) {
new TelnetConnection();
}
}
packagetelnet;
输入游戏背景;
导入game.TargetStrategy;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入java.io.OutputStream;
导入java.net.InetAddress;
导入java.net.SocketException;
导入java.util.Deque;
导入java.util.Observable;
导入java.util.Observer;
导入java.util.Properties;
导入java.util.logging.Logger;
导入org.apache.commons.net.telnet.TelnetClient;
导入model.GameAction;
导入model.GameData;
导入model.TelnetEventProcessor;
公共类TelnetConnection实现了Observer{
私有静态记录器log=Logger.getLogger(TelnetConnection.class.getName());
私有TelnetClient TelnetClient=新TelnetClient();
私有InputOutput=新的InputOutput();
私有TelnetEventProcessor解析器=新的TelnetEventProcessor();
私有上下文;/=新的LogicalContext();
公共TelnetConnection(){
试一试{
init();
}捕获(SocketException例外){
}捕获(FileNotFoundException ex){
}捕获(IOEX异常){
}
}
private void init()抛出SocketException、FileNotFoundException、IOException{
Properties props=PropertiesReader.getProps();
InetAddress主机=InetAddress.getByName(props.getProperty(“主机”);
int-port=Integer.parseInt(props.getProperty(“端口”);
telnetClient.connect(主机、端口);
inputOutput.readWriteParse(telnetClient.getInputStream(),telnetClient.getOutputStream());
inputOutput.addObserver(此);
addObserver(this);
}
私有void sendAction(GameAction操作)引发IOException{
log.fine(action.toString());
字节[]actionBytes=action.getAction().getBytes();
OutputStream OutputStream=telnetClient.getOutputStream();
outputStream.write(actionBytes);
outputStream.write(13);
outputStream.write(10);
outputStream.flush();
}
私有void sendActions(Deque gameActions){
而(!gameActions.isEmpty()){
GameAction=gameActions.remove();
试一试{
行动(行动);
}捕获(IOEX异常){
}
}
}
@凌驾
公共无效更新(可观察o,对象arg){
GameData数据=null;
字符串行=null;
德克动作;
if(输入输出的o实例){
if(arg instanceof String){
line=arg.toString();
parser.parse(行);
}else if(游戏数据的arg实例){
数据=(游戏数据)参数;
上下文=新上下文(新TargetStrategy());
context.setGameData(data);//数据经常更改!
//战略取决于数据
//把这些都放到另一节课上?
gameActions=context.executeStrategy();
发送动作(游戏动作);
}否则{
日志信息(“非i/o参数”);
}
}else if(o TelnetEventProcessor的实例){
if(游戏数据的arg实例){
log.info(“游戏数据参数”);
数据=(游戏数据)参数;
gameActions=context.executeStrategy();
发送动作(游戏动作);
}否则{
log.info(“不是telnetevent参数”);
}
}
}
公共静态void main(字符串[]args){
新的TelnetConnection();
}
}
我对此不太满意:
package game;
import model.GameData;
public class RulesForStrategy {
private Context context = null;
private GameData gameData = null;
private RulesForStrategy() {
}
public RulesForStrategy(GameData gameData) {
this.gameData = gameData;
}
public Context getContext() {
context = new Context(new TargetStrategy());
context.setGameData(gameData);
return context;
}
}
因为它不能解决根本问题,没有数据的上下文不应该存在
然而,我想它会起作用