设计模式系列(二十一)状态模式

参考:https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/state.html

https://www.cnblogs.com/java-my-life/archive/2012/06/08/2538146.html

https://www.cnblogs.com/haoerlv/p/7777789.html

一:基本原理

  定义:(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

               1、有一个对象,它是有状态的。

               2、这个对象在状态不同的时候,行为不一样。

               3、这些状态是可以切换的,而非毫无关系。

状态模式包含如下角色:

                  Context:它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。

                  State:状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。

                  ConcreteState:具体状态,实现相关行为的具体状态类。

 

  • ../_images/State.jpg

上代码

代码一

public interface State {
    /**
     * 状态对应的处理
     */
    public void handle(String sampleParameter);
}
public class ConcreteStateA implements State {

    @Override
    public void handle(String sampleParameter) {
        
        System.out.println("ConcreteStateA handle :" + sampleParameter);
    }

}
public class ConcreteStateB implements State {

    @Override
    public void handle(String sampleParameter) {
        
        System.out.println("ConcreteStateB handle :" + sampleParameter);
    }

}
public class Context {
    //持有一个State类型的对象实例
    private State state;

    public void setState(State state) {
        this.state = state;
    }
    /**
     * 用户感兴趣的接口方法
     */
    public void request(String sampleParameter) {
        //转调state来处理
        state.handle(sampleParameter);
    }
}
public class Client {

    public static void main(String[] args){
        //创建状态
        State state = new ConcreteStateB();
        //创建环境
        Context context = new Context();
        //将状态设置到环境中
        context.setState(state);
        //请求
        context.request("test");
    }
}

代码二

public interface RunState {

    void run(Hero hero);
    
}
public class CommonState implements RunState{

    public void run(Hero hero) {
        //正常跑动则不打印内容,否则会刷屏
    }

}
public class SpeedUpState implements RunState{

    public void run(Hero hero) {
        System.out.println("--------------加速跑动---------------");
        try {
            Thread.sleep(4000);//假设加速持续4秒
        } catch (InterruptedException e) {}
        hero.setState(Hero.COMMON);
        System.out.println("------加速状态结束,变为正常状态------");
    }
    
}
public class SpeedDownState implements RunState{

    public void run(Hero hero) {
        System.out.println("--------------减速跑动---------------");
        try {
            Thread.sleep(4000);//假设减速持续4秒
        } catch (InterruptedException e) {}
        hero.setState(Hero.COMMON);
        System.out.println("------减速状态结束,变为正常状态------");
    }

}
public class SwimState implements RunState{

    public void run(Hero hero) {
        System.out.println("--------------不能跑动---------------");
        try {
            Thread.sleep(2000);//假设眩晕持续2秒
        } catch (InterruptedException e) {}
        hero.setState(Hero.COMMON);
        System.out.println("------眩晕状态结束,变为正常状态------");
    }

}
public class Hero {
    
    public static final RunState COMMON = new CommonState();//正常状态
    
    public static final RunState SPEED_UP = new SpeedUpState();//加速状态
    
    public static final RunState SPEED_DOWN = new SpeedDownState();//减速状态
    
    public static final RunState SWIM = new SwimState();//眩晕状态
    
    private RunState state = COMMON;//默认是正常状态
    
    private Thread runThread;//跑动线程
    
    //设置状态
    public void setState(RunState state) {
        this.state = state;
    }
    //停止跑动
    public void stopRun() {
        if (isRunning()) runThread.interrupt();
        System.out.println("--------------停止跑动---------------");
    }
    //开始跑动
    public void startRun() {
        if (isRunning()) {
            return;
        }
        final Hero hero = this;
        runThread = new Thread(new Runnable() {
            public void run() {
                while (!runThread.isInterrupted()) {
                    state.run(hero);
                }
            }
        });
        System.out.println("--------------开始跑动---------------");
        runThread.start();
    }
    
    private boolean isRunning(){
        return runThread != null && !runThread.isInterrupted();
    }

}

二:使用

登录功能设计

参考:https://www.cnblogs.com/vegetate/p/9997193.html

public class MainActivity extends Activity {  
    @Override  
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {  
        super.onCreate(savedInstanceState, persistentState);  
        //转发按钮  
        findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                LoginContext.getLoginContext().forward(MainActivity.this);  
            }  
        });  
        //注销按钮  
        findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                LoginContext.getLoginContext().setState(new LogoutState());  
            }  
        });  
    }  
}  
public class LoginActivity extends Activity {  
    EditText user;  
    EditText pwd;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {  
        super.onCreate(savedInstanceState, persistentState);  
        findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                login();  
                finish();  
            }  
        });  
    }  
  
    private void login() {  
        String name = user.getText().toString();  
        String pwd1 = pwd.getText().toString();  
        //执行网络请求  
        //登录成功后修改为已登录状态  
        LoginContext.getLoginContext().setState(new LoginedState());  
    }  
public class LoginContext {  
    UserState mState = new LogoutState();  
    static LoginContext sLoginContext = new LoginContext();  
  
    private LoginContext() {  
  
    }  
  
    public static LoginContext getLoginContext() {  
        return sLoginContext;  
    }  
  
    public void setState(UserState aState) {  
        this.mState = aState;  
    }  
  
    public void forward(Context context) {  
        mState.forward(context);  
    }  
  
    public void comment(Context context) {  
        mState.comment(context);  
    }  
}  
public interface UserState {  
    public void forward(Context context);  
  
    public void comment(Context context);  
}  
/****************************************** 
 * 类名称:LoginedState 
 * 类描述:已登录状态 
 * @time: 2016/11/16 14:13 
 ******************************************/  
public class LoginedState implements UserState {  
    @Override  
    public void forward(Context context) {  
        Log.i("TAG", "转发");  
    }  
  
    @Override  
    public void comment(Context context) {  
        Log.i("TAG", "评论");  
    }  
}
public class LogoutState implements UserState {  
    @Override  
    public void forward(Context context) {  
        goToLogin(context);  
    }  
  
    @Override  
    public void comment(Context context) {  
        goToLogin(context);  
    }  
  
    private void goToLogin(Context context) {  
        Intent intent = new Intent(context, LoginActivity.class);  
        context.startActivity(intent);  
    }  
}  

如果不使用状态模式,在任何调用这些功能时都要进行是否登录的判断,代码逻辑就变成If-else,如果再增加用户一个状态,还需要再支持对这个状态的判断,使得模块很脆弱,一单忘记某个用户状态进行判断,很容易引发用户权限问题,

State模式将所有与一个特定的状态相关的行为都放入一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性与可维护性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值