我有一个与设计和对象结构相关的问题。这是问题陈述:
- 我有一个机器人对象,它可以自行穿越地面。它将被提供移动指令并且它必须相应地解析。例如样本输入将是: A。向右旋转|移动|向左旋转|移动|移动|移动
其中 move 是网格上的单位移动。
我用 java 做了一个非常基础的设计。 (下面粘贴了完整的代码)
package com.roverboy.entity;
import com.roverboy.states.RotateLeftState;
import com.roverboy.states.RotateRightState;
import com.roverboy.states.State;
public class Rover {
private Coordinate roverCoordinate;
private State roverState;
private State rotateRight;
private State rotateLeft;
private State move;
public Rover() {
this(0, 0, Compass.NORTH);
}
public Rover(int xCoordinate, int yCoordinate, String direction) {
roverCoordinate = new Coordinate(xCoordinate, yCoordinate, direction);
rotateRight = new RotateRightState(this);
rotateLeft = new RotateLeftState(this);
move = new MoveState(this);
}
public State getRoverState() {
return roverState;
}
public void setRoverState(State roverState) {
this.roverState = roverState;
}
public Coordinate currentCoordinates() {
return roverCoordinate;
}
public void rotateRight() {
roverState = rotateRight;
roverState.action();
}
public void rotateLeft() {
roverState = rotateLeft;
roverState.action();
}
public void move() {
roverState = move;
roverState.action();
}
}
package com.roverboy.states;
public interface State {
public void action();
}
package com.roverboy.entity;
import com.roverboy.states.State;
public class MoveState implements State {
private Rover rover;
public MoveState(Rover rover) {
this.rover = rover;
}
public void action() {
rover.currentCoordinates().setXCoordinate(
(Compass.EAST).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getXCoordinate() + 1 : rover.currentCoordinates()
.getXCoordinate());
rover.currentCoordinates().setXCoordinate(
(Compass.WEST).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getXCoordinate() - 1 : rover.currentCoordinates()
.getXCoordinate());
rover.currentCoordinates().setYCoordinate(
(Compass.NORTH).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getYCoordinate() + 1 : rover.currentCoordinates()
.getYCoordinate());
rover.currentCoordinates().setYCoordinate(
(Compass.SOUTH).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getYCoordinate() - 1 : rover.currentCoordinates()
.getYCoordinate());
}
}
package com.roverboy.states;
import com.roverboy.entity.Rover;
public class RotateRightState implements State {
private Rover rover;
public RotateRightState(Rover rover) {
this.rover = rover;
}
public void action() {
rover.currentCoordinates().directionOnRight();
}
}
package com.roverboy.states;
import com.roverboy.entity.Rover;
public class RotateLeftState implements State {
private Rover rover;
public RotateLeftState(Rover rover)
{
this.rover = rover;
}
public void action() {
rover.currentCoordinates().directionOnLeft();
}
}
package com.roverboy.entity;
public class Coordinate {
private int xCoordinate;
private int yCoordinate;
private Direction direction;
{
Direction north = new Direction(Compass.NORTH);
Direction south = new Direction(Compass.SOUTH);
Direction east = new Direction(Compass.EAST);
Direction west = new Direction(Compass.WEST);
north.directionOnRight = east;
north.directionOnLeft = west;
east.directionOnRight = north;
east.directionOnLeft = south;
south.directionOnRight = west;
south.directionOnLeft = east;
west.directionOnRight = south;
west.directionOnLeft = north;
direction = north;
}
public Coordinate(int xCoordinate, int yCoordinate, String direction) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.direction.face(direction);
}
public int getXCoordinate() {
return xCoordinate;
}
public void setXCoordinate(int coordinate) {
xCoordinate = coordinate;
}
public int getYCoordinate() {
return yCoordinate;
}
public void setYCoordinate(int coordinate) {
yCoordinate = coordinate;
}
public void directionOnRight()
{
direction.directionOnRight();
}
public void directionOnLeft()
{
direction.directionOnLeft();
}
public String getFacingDirection()
{
return direction.directionValue;
}
}
class Direction
{
String directionValue;
Direction directionOnRight;
Direction directionOnLeft;
Direction(String directionValue)
{
this.directionValue = directionValue;
}
void face(String directionValue)
{
for(int i=0;i<4;i++)
{
if(this.directionValue.equalsIgnoreCase(directionValue))
break;
else
directionOnRight();
}
}
void directionOnRight()
{
directionValue = directionOnRight.directionValue;
directionOnRight = directionOnRight.directionOnRight;
directionOnLeft = directionOnRight.directionOnLeft;
}
void directionOnLeft()
{
directionValue = directionOnLeft.directionValue;
directionOnRight = directionOnLeft.directionOnRight;
directionOnLeft = directionOnLeft.directionOnLeft;
}
}
现在我怀疑最后一类“方向”和“坐标”。 coordinate 表示流动站的坐标对象,帮助它保持方向。目前,为了跟踪方向,我正在使用 Direction 对象的双向链表,它的工作原理很像指南针。向左或向右旋转。
这是我的问题。 1. 我使用了状态模式并展示了方向跟踪的设计。有没有更好的方法来简化这个?雷姆。我需要正确维护坐标;这样,如果您朝 +y 轴移动,我的坐标应该在 + 中,否则在负中。 X 轴也一样。
目前,改变流动站表面的责任间接委托(delegate)给了坐标和方向类。这真的正确吗?漫游者不负责保持方向吗?在我的设计中,将责任委托(delegate)给协调和指导类真的是正确的吗?只是因为在那里更容易操纵它?
我们非常欢迎任何简单的设计改进和代码建议。随意批评。
感谢您的耐心等待和反馈;提前。
最佳答案
这是我前几天想出的一个方向枚举,我可能非常喜欢它。也许您会发现它在您的代码中很有用。
import java.awt.Point;
public enum Direction {
E(1, 0), N(0, 1), W(-1, 0), S(0, -1);
private final int dy;
private final int dx;
private Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
public Direction left() {
return skip(1);
}
public Direction right() {
return skip(3);
}
public Direction reverse() {
return skip(2);
}
private Direction skip(int n) {
final Direction[] values = values();
return values[(ordinal() + n) % values.length];
}
public Point advance(Point point) {
return new Point(point.x + dx, point.y + dy);
}
}
关于java - 设计和对象责任的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1240643/