【设计模式】——18,状态模式

(十八)状态模式

状态模式(State Pattern)允许对象在内部状态发生变化时改变他的状态,类的行为是基于它的状态改变的。

1,状态模式的设计原则

1,环境类(Context):定义客户端需要的接口,内部维护一个当前状态实例,负责状态切换;

2,抽象状态(IState):定义状态的行为;

3,具体状态(Concreate):具体状态的行为。

image-20210318142941479

2,简单例子

我们在社区阅读文章时,评论和收藏等操作都是需要在登录状态下进行的,否则将统一跳转到登录页面。下面就利用状态模式实现上述场景。

public abstract class UserState {
    
    
//    状态接口需要维护一个context
    protected AppContext appContext;

    public void setAppContext(AppContext appContext) {
    
    
        this.appContext = appContext;
    }

    public abstract void favorite();
    public abstract void comment(String comment);
}
public class LoginState extends UserState {
    
    
    @Override
    public void favorite() {
    
    
        System.out.println("收藏成功!");
    }

    @Override
    public void comment(String comment) {
    
    
        System.out.println(comment);
    }
}
public class UnLoginState extends UserState {
    
    
//    未登录状态下的行为多了一个切换操作
    @Override
    public void favorite() {
    
    
        this.switch2Login();
        this.appContext.getState().favorite();
    }

    @Override
    public void comment(String comment) {
    
    
        this.switch2Login();
        this.appContext.getState().favorite();
    }
//    切换到登录
    public void switch2Login(){
    
    
        System.out.println("跳转到登录页面!");
        this.appContext.setState(this.appContext.STATE_LOGIN);
    }
}
public class AppContext {
    
    
//    context内部维护两种状态
    public static final UserState STATE_LOGIN = new LoginState();
    public static final UserState STATE_UNLOGIN = new UnLoginState();

    private UserState currentState = STATE_UNLOGIN;

//    代码块初始化状态对应的context
    {
    
    
        STATE_LOGIN.setAppContext(this);
        STATE_UNLOGIN.setAppContext(this);
    }
//   设置状态,同时设置当前状态的context
    public void setState(UserState state){
    
    
        this.currentState = state;
        this.currentState.setAppContext(this);
    }
    public UserState getState(){
    
    
        return this.currentState;
    }
//    内部需要维护当前状态的方法
    public void favorite(){
    
    
        this.currentState.favorite();
    }

    public void comment(String comment){
    
    
        this.currentState.comment(comment);
    }
}
public class Client {
    
    
    public static void main(String[] args) {
    
    
        AppContext appContext = new AppContext();
        appContext.favorite();
        appContext.comment("我赞!");
    }
}
跳转到登录页面!
收藏成功!
我赞!

image-20210318145954302

3,状态模式的点评

状态模式通过context对状态进行切换,很好的封装了转换细节。但是他违背了开闭原则,必须要知道所有的状态。

状态模式和责任链模式相比:状态模式个状态知道下一状态,而责任链模式不知道,它封装在客户端里;

状态模式和策略模式相比:状态间相互关系,策略间相互独立。

猜你喜欢

转载自blog.csdn.net/qq_40589204/article/details/118343231