java 状态设计模式--如何用开闭原则实现它

vfh0ocws  于 2023-05-15  发布在  Java
关注(0)|答案(1)|浏览(113)

我在Java中实现了状态设计模式,有两种状态:锁定和解锁。初始状态为锁定。如果用户输入代码(密码),则变为解锁状态,然后如果用户输入“0”,则变为锁定状态。
我当前代码实现的问题是,如果我想添加另一个状态-例如:SemiLocked,我还必须更改Locked,Unlocked类中的evKey函数,以便它们允许转换到SemiLocked的新状态。(例如:用户输入正确的代码将不再更改为“解锁”,而是更改为“半锁定”)
如果我将来添加更多的状态,如何用更少的必要更改更好地实现它?
当前代码:

public class SecretKeeper {
    private int secretCode;
    String secret1, secret2;
    private State state = new Locked(); 

    public SecretKeeper(int secretCode, String secret1, String secret2){
        this.secretCode=secretCode;
        this.secret1=secret1;
        this.secret2=secret2;
    }

    void printSecret1(){
        System.out.println(secret1);
    }

    void printSecret2(){
        System.out.println(secret2);
    }

    public boolean checkCode(int code){
        return code==secretCode;
    }

    void evKey(int digit){
        state.evKey(this, digit);
    }
    
    public void setState(State state) {
        this.state = state;
    }
}

public interface State {
    void evKey(SecretKeeper sk, int digit);
}
 
public class Locked implements State{
    int code = 0;
    @Override
    public void evKey(SecretKeeper sk, int digit) {
        if (digit == 0) code = 0;
        else code = code*10+digit;
        if (sk.checkCode(code)) sk.setState(new Unlocked());
    }
}

public class Unlocked implements State{
    @Override
    public void evKey(SecretKeeper sk, int digit) {
        if (digit == 0) sk.setState(new Locked());
        else if (digit == 1) sk.printSecret1();
        else if (digit == 2) sk.printSecret2();
    }
}
rqcrx0a6

rqcrx0a61#

下面是一个遵循OCP的示例。

public class SecretKeeper {
    private int secretCode;
    private String secret1, secret2;
    private State state;

    //...

  void evKey(int digit) {
        state.setCode(digit);
        state.doStuff();
        boolean isSuccess = checkCode(state.getCode());
        if(isSuccess){
            state = state.getSwitchedState();
        }
    }

    //...
}
public interface State {
    void setCode(int digit);
    int getCode();
    State getSwitchedState();
    void doStuff();
}
public class LockedState implements State {
    private int code = 0;

    @Override
    public void setCode(int digit) {
        if (digit == 0) code = 0;
        else code = code * 10 + digit;
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public State getSwitchedState() {
        return new SemiLockedState();
    }

    @Override
    public void doStuff() {
        // implement behavior for LockedState
    }
}

public class UnlockedState implements State {
    private int code = 0;

    @Override
    public void setCode(int digit) {
        code = digit;
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public State getSwitchedState() {
        return new LockedState(); // Modify as per requirement
    }

    @Override
    public void doStuff() {
       if (getCode() == 1) SecretKeeper.printSecret1();
       else if (getCode() == 2) SecretKeeper.printSecret2();
       
    }
}

相关问题