设计和客体责任的问题 [英] A question of design and object responsibility

查看:108
本文介绍了设计和客体责任的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 我有一个机器人对象,假设自己穿过地面。它将提供移动指令,它必须相应地解析。例如,输入样本是:
    a。 RotateRight | Move | RotateLeft | Move | Move | 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;

私人状态rotateRight;
private State rotateLeft;私人状态移动


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();
}
}


包com.roverboy.states;

public interface State {

public void action();
}

package com.roverboy.entity;

import com.roverboy.states.State;

public class MoveState实现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());
}
}


包com.roverboy.states;

import com.roverboy.entity.Rover;

public class RotateRightState实现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实现State {

private Rover rover;

public RotateLeftState(Rover rover)
{
this.rover = rover;
}

public void action(){
rover.currentCoordinates()。directionOnLeft();
}

}


包com.roverboy.entity;

public class Coordinate {

private int xCoordinate;
private int yCoordinate;
私人方向;
{
Direction north = new Direction(Compass.NORTH);
方向南=新方向(Compass.SOUTH);
方向east = new Direction(Compass.EAST);
方向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;
}
}

类方向
{
String directionValue;
方向directionOnRight;
方向directionOnLeft;

方向(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;
}
}

现在我怀疑是最后一个类方向和协调。坐标表示流动站的坐标对象,有助于维护其方向。目前为了跟踪方向,我使用了一个双向的方向对象列表,它几乎像罗盘一样工作。向左或向右旋转



这是我有的问题。
1.我已经使用状态模式和显示设计方向跟踪。有没有更好的方法来简化这个呢?雷姆。我需要正确维护坐标;这样,如果你移动到+ y轴,我的坐标应该在+ else中减去。 X轴相同。


  1. 目前,改变流动站面部的责任被间接委托给坐标和方向课。这是真的吗?流域车是否负责维护方向?我在设计中真的很正确地将这种责任下放到协调和方向课;只是因为它更容易操纵它?


  2. 对代码的任何简单的设计改进和建议将是最受欢迎的。随意批评。


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

解决方案

您正在要求如何简化。如果我可以提出大胆的建议,为什么不使用一个不透明的int来指导,并且有一个静态类来处理它?通过opaque int我的意思是你的代码永远不会直接使用它,而只是作为Direction类的参数。



这里有一些部分java风格的伪代码来显示我的意思。

  // 0 = east,1 = north,2 = west,... 
public class Direction {
static int [] moveX = [1,0,-1,0];
static final int NORTH = 1;
//在给定方向移动一步后的坐标
static Pair move(int direction,Pair old){
return new Pair(old.x + moveX [direction],old.y + moveY [direction]);
}
static int turnLeft(int direction){
return(direction + 1)%4;
}
static int turnRight(int direction){
return(direction + 3)%4;
}
}

这种做事的方式将具有使用更少的分配,所以垃圾收集器不需要经常运行。另一个优点是设计保持面向对象的意义上,如果稍后您可以通过例如旋转方式,您可以轻松地更改方向类。一次45度。



为了回答您的其他问题,我认为向Direction类委托沿一定方向更改坐标的任务是非常好的。流动站将负责维护方向,只有在流动站对象将包含一个int字段来存储其所面向的方向的意义上。


I have a design and object structuring related question. Here is the problem statement:

  1. I have a Robot object which is suppose to traverse the ground on its own. It would be provided movement instructions and it must parse accordingly. For example sample input would be: a. RotateRight|Move|RotateLeft|Move|Move|Move

Where move is a unit movement on a grid.

I did a very basic design in java. (Complete Code Pasted below)

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;      
    }
}

Now my doubt is with this last class "Direction" and "Coordinate". coordinate represents a coordinate object for rover which helps it maintain its direction. Currently to keep track of direction I am using a doubly linked list of Direction objects, which pretty much work like a compass. Rotate left or right.

Here are the questions that I have. 1. I have used state pattern and shown design for direction tracking. Is there a better approach to simplify even this? Rem. I need to maintain coordinates correctly; such that if you move towards +y axis, my coordinates should be in + else in minus. Same for X axis.

  1. Currently the responsibility for changing the face of the rover is indirectly delegated to coordinates and to direction class. Is this really correct? Isn't rover responsible for maintaining direction? Am I really right in my design to delegate that responsibility down to coordinate and direction class; just because it is easier to manipulate it there?

  2. Any simple design improvements and suggestions on code will be most welcome. Feel free to critique.

Thanks for your patience and feedback; in advance.

解决方案

You're asking for how to simplify. If I may suggest something bold, why not use an opaque int for direction and have a static class to deal with it? By "opaque int" I mean that your code would never use it directly, but only as argument to the Direction class.

Here's some partial java-styled pseudocode to show what I mean.

// 0 = east, 1 = north, 2 = west, ...
public class Direction {
  static int [] moveX = [ 1, 0, -1, 0];
  static final int NORTH = 1;
  // coordinates after moving one step in the given direction
  static Pair move(int direction, Pair old) {
     return new Pair( old.x + moveX[direction] , old.y + moveY[direction] );
  }
  static int turnLeft(int direction) { 
     return (direction+1) % 4;
  }
  static int turnRight(int direction) {
     return (direction+3) % 4;
  }
}

This way of doing things would have the advantage of using fewer allocations, so the garbage collector won't need to run as often. Another advantage is that the design remains object-oriented in the sense that you can easily change the direction class if later you want to be able to rotate by e.g. 45 degrees at a time.

To answer your other questions, I think it's perfectly fine to delegate to the Direction class the task of changing a coordinate along a certain direction. The rover would be responsible for maintaining direction only in the sense that the rover object would contain an int field to store the direction it's facing.

这篇关于设计和客体责任的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆