java - 设计和对象责任的问题

标签 java design-patterns oop

我有一个与设计和对象结构相关的问题。这是问题陈述:

  1. 我有一个机器人对象,它可以自行穿越地面。它将被提供移动指令并且它必须相应地解析。例如样本输入将是: 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 轴也一样。

  1. 目前,改变流动站表面的责任间接委托(delegate)给了坐标和方向类。这真的正确吗?漫游者不负责保持方向吗?在我的设计中,将责任委托(delegate)给协调和指导类真的是正确的吗?只是因为在那里更容易操纵它?

  2. 我们非常欢迎任何简单的设计改进和代码建议。随意批评。

感谢您的耐心等待和反馈;提前。

最佳答案

这是我前几天想出的一个方向枚举,我可能非常喜欢它。也许您会发现它在您的代码中很有用。

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/

相关文章:

java - 使用静态工厂样式构造函数将元素添加到一个或多个静态列表

python - Python中的工厂模式

java - 从 JTextArea 获取用户输入

java - 正确使用 Entity 和 DTO 以在 Restful Web 服务中提供 Json

design-patterns - 如何编写布局管理器?

python - 使用 super() 访问第二个基类的方法

java - 我不明白 'this' 与父类(super class)一起使用

java - 在 XSLT 中对记录进行分组时如何避免 O(n^2) 的复杂性?

java - 如何使用从其他方法中学到的知识?

java - 为 java 更改 itext 中的特定 PdfPCell?