简体   繁体   English

状态设计模式

[英]state design pattern

I am trying to implement the state pattern but the problem is, that I am not changing the states and when I use a test class it is using the concrete class that has a relationship with the interface.我正在尝试实现状态模式,但问题是,我没有更改状态,当我使用测试类时,它使用的是与接口有关系的具体类。

For example in the fire and move methods in the state classes are not working and returning the result of the Railgun.例如,状态类中的 fire 和 move 方法不起作用并返回 Railgun 的结果。

Here is the code:这是代码:

public interface RailgunState 
{

    public String fire(Point p, int rounds);
    public String move(Point p);
}

public class Railgun 
{
    /**
     * @param ammo repersent the current ammonitions.
     */
     int ammo = 0;
     /**
     * @param MAX_AMMO repersent the maximum ammonitions.
     */
      public static int MAX_AMMO = 10;
    int test = 10;
    /**
     *@param position represent the possition of the state 
     */
    Point position;
    Point point;
    //ask mark
    int x = 0;
    int y = 0;
    int result = 6;
    /**
     * @param damagedState represent an object of DamagedState
     */
    RailgunState damagedState ;
    RailgunState needAmmoState ;
    RailgunState normalState ;
     /**
     * @param state represent the state of the RailGun
     */
    RailgunState state; 

    Railgun()
    {
        damagedState = new DamagedState();
        needAmmoState = new NeedAmmoState();
        normalState = new NormalState();
        state = normalState;
    }
    /** fire().
     * @param p is the coordinates of the target
     * @param rounds number of rounds HQ has requested
     * @return success/ partial success/ failure
     */
    public String fire(Point p, int rounds)
    {
         return "Fire order: Success 6/6";
    }

    /**  move(). success or failure only the string
     * @param p is the destination
     * @return success or failure when a railgun can move to the destination
     */
    public String move(Point p)
    {
        position = p;
        return  "Move order: Success" ; 
    }

    /**getPosition().
     * @return the possstion of the point 
     */
    public Point getPosition()
    {             
        return position ;
    }

    void setPosition(Point position)
    {
        this.position = position;
    }

     public RailgunState getState()
    {
        return state;
    }

    void setAmmo(int ammo) 
    {
        this.ammo = ammo;
    }

    public Point getPoint() {
        return point;
    }

    public RailgunState getDamagedState() {
        return damagedState;
    }

    public RailgunState getNeedAmmoState() {
        return needAmmoState;
    }

    public RailgunState getNormalState() {
        return normalState;
    }

    int getAmmo()
    {
        return MAX_AMMO;
    }

    void setState(RailgunState state)
    {
         this.state = state;
    }
    void setState(NeedAmmoState needAmmoState)
    {
        this.state = needAmmoState;
    }

    void setState(NormalState normal)
    {
        this.state = normalState;
    }
        void setState(DamagedState damagedState)
    {
        this.state = damagedState;
    }
}


public class NormalState implements RailgunState {

    Railgun railgun;    
    static int MAX_AMMO = 10;
    int result = 6;

    NormalState()
    {
    }
    @Override
    public String fire(Point p, int rounds) 
    {
        MAX_AMMO -= rounds;
        if((MAX_AMMO >= 0) && (rounds == result))
        {
            NeedAmmoState needAmmo = new NeedAmmoState();
            System.out.println("Seccuees: " + MAX_AMMO);
            NormalState state = new NormalState();
            railgun.setState(state);
            return "Fire order: Success 6/6";
        }
        else if((MAX_AMMO < 0) && (MAX_AMMO != -result))
        {
              System.out.println("Partial: " + MAX_AMMO);
              Railgun.MAX_AMMO = 0;
              System.out.println("Partial: " + MAX_AMMO);
              NeedAmmoState needAmmo = new NeedAmmoState();
              railgun.setState(needAmmo);
              return "Fire order: Partial success 4/6";
        }

        else 
        {
             System.out.println("Fail: " + MAX_AMMO);
             DamagedState damaged = new DamagedState();
             railgun.setState(damaged);
             return "Fire order: Failure 0/6";
        }
    }

    @Override
    public String move(Point p)
    {
        return p + "";
    }

    /**getPosition().
     * @return the possstion of the point 
     */
    public Point getPosition()
    {             
        return railgun.getPosition();
    }
}


public class NeedAmmoState implements RailgunState
{
    Point position;
    Railgun railgun;
    NeedAmmoState()
    {
    }

    @Override
    public String fire(Point p, int rounds)
    {
          return "Fire order: Failed 0/4";
    }

    @Override
    public String move(Point p)
    {
        railgun = new Railgun();
         railgun.move(p);
        position = p;
        return  "Move order: Success" ; 
    }

    void setPosition(Point position)
    {
        this.position = position;
    }
    int getAmmo()
    {
        return Railgun.MAX_AMMO;
    }

    /**getPosition().
     * @return the possstion of the point 
     */
    public Point getPosition()
    {             
        int x = 320;
        int y = 43;
        Point p = new Point(x,y);
        return p;
    }
}


public class NormalStateTest {

    /**
     * Test of fire method, of class NormalState.
     */
    @Test
    public void testFire() {
        final Railgun railgun = new Railgun();
        railgun.setState(new NormalState());
        final int numRounds = 6;
        final int x = 100;
        final int y = 340;

        // This fire mission should be completely successful
        String actualResult = railgun.fire(new Point(x, y), numRounds);
        String expectedResult = "Fire order: Success 6/6";
        //System.out.println(actualResult);
        assertEquals(expectedResult, actualResult);

        // This fire mission should be partially successful
        actualResult = railgun.fire(new Point(x, y), numRounds);
        //System.out.println(actualResult);
        expectedResult = "Fire order: Partial success 4/6";
        assertEquals(expectedResult, actualResult);

        // This fire mission should fail
        actualResult = railgun.fire(new Point(x, y), numRounds);
        //System.out.println(actualResult);
        expectedResult = "Fire order: Failure 0/6";
        assertEquals(expectedResult, actualResult);

        // Check state change to NeedAmmo state
        assertEquals(railgun.getState().getClass(), NeedAmmoState.class); 
    }

    /**
     * Test of move method, of class NormalState. Should always succeed.
     */
    @Test
    public void testMove() {
        final Railgun railgun = new Railgun();
        final int x = 129;
        final int y = 444;
        final String actualResult = railgun.move(new Point(x, y));
        final String expectedResult = "Move order: Success";
        System.out.println(actualResult);
        assertEquals(new Point(x, y), railgun.getPosition());
        assertEquals(expectedResult, actualResult);
    }
}

So the problem is that when testing in NormalStateTest.java for example, the result of the classes like NormalState and NeedAmmoSate are returning the values from the Railgun in the methods fire and move.所以问题是,例如在 NormalStateTest.java 中进行测试时,NormalState 和 NeedAmmoSate 等类的结果在方法 fire 和 move 中返回来自 Railgun 的值。

If you want the RailGun.fire() method delegate to the current state fire() method, then do so.如果您希望RailGun.fire()方法委托给当前状态的fire()方法,请执行此操作。 In your code, it returns a hard-coded string and doesn't use the state at all.在您的代码中,它返回一个硬编码的字符串并且根本不使用状态。

Change改变

public String fire(Point p, int rounds) {
     return "Fire order: Success 6/6";
}

to

public String fire(Point p, int rounds) {
     return state.fire(p, rounds);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM