简单实现状态机

状态机的实现场景在于不同的状态下对于同一行为有着不同的响应,即将if-else用多态来实现。通常情况下if-else火switch-case形式下根据不同的状态进行判断,如果是状态A就执行A响应,如果是状态B就执行B响应,但这种实现使得所有的逻辑耦合在一起,一旦状态较多并且状态之间有先后制约关系,就会很容易出错,通过状态机模式能够很好的避免这种问题。并且使代码更加清晰明了。

下面简单实现一个用户登录系统:

例如微博页面用户在未登录情况下点击转发按钮,此时会让用户先进行登录,然后执行转发动作,如果是已登录状态,用户可以直接进行转发操作。在登录和未登录的两种状态下对于转发这一操作有着不同的处理,当登录状态发生改变后转发的操作行为也发生了改变。

Demo中有MainActivity,LoginActivity,MainActivity有转发和注销登录功能,LoginAcitity为登录界面:

首先用户的默认状态为未登录状态,此时用户点击转发按钮会先跳转到登录界面执行登录,登录完成后回到MainActivity页面,此时用户点击转发可以直接进行转发。

MainActivity代码如下:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //转发
        findViewById(R.id.forward_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginContext.getLoginContext().forward(MainActivity.this);
            }
        });
        //注销
        findViewById(R.id.logout_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginContext.getLoginContext().setmState(new LogoutState());
            }
        });
    }
}

 

LoginActivity是在用户输入用户名和密码后执行登录,成功之后将LoginContext的状态设置为登录状态,并且返回MainActivity页面,代码如下:

public class LoginActivity extends AppCompatActivity {

    private EditText userNameEditText;
    private EditText pswEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        userNameEditText=(EditText)findViewById(R.id.usename);
        pswEditText=(EditText)findViewById(R.id.psw);

        //登陆按钮
        findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                login();
                finish();
            }
        });
    }
    private void login() {
        String username = userNameEditText.getText().toString().trim();
        String psw = pswEditText.getText().toString().trim();

        //执行登陆网络请求

        //登陆成功后将状态修改为登陆状态
        LoginContext.getLoginContext().setmState(new LogoutState());


    }
}

LoginContext是状态机的状态管理类,LoginContext将用户的相关操作委托给具体执行动作的状态类,当状态改变后(即LoginContext.getLoginContext().setmState(new LogoutState())),LoginContext的状态就

发生了改变,转发操作也发生了改变。代码如下:

public class LoginContext {
    //用户状态  默认为未登录状态
    UserState mState = new LogoutState();
    //单例
    static LoginContext sLoginContext = new LoginContext();

    private LoginContext(){};

    public static LoginContext getLoginContext(){
        return sLoginContext;
    }

    public void setmState(UserState userState){
        mState = userState;
    }

    //转发
    public void forward(Context context){
        mState.forward(context);
    }

    //评论
    public void comment(Context context){
        mState.comment(context);
    }
}

LoginContext通过setState来对状态进行修改,并将操作委托给操作对象,不同的状态对象对于同一个操作进行了不同的处理,状态对象相关代码如下:

/**
 * 用户状态
 */
public interface UserState {
    /**
     * 登陆
     * @param context
     */
    public void forward(Context context);

    /**
     * 分享
     * @param context
     */
    public void comment(Context context);
}
/**
 * 登录状态
 */
public class LoginState implements UserState {
    @Override
    public void forward(Context context) {
        Toast.makeText(context,"转发消息",Toast.LENGTH_LONG).show();
    }

    @Override
    public void comment(Context context) {
        Toast.makeText(context,"评论消息",Toast.LENGTH_LONG).show();
    }
}
/**
 * 注销状态
 */
public class LogoutState implements UserState {
    @Override
    public void forward(Context context) {
        gotoLoginActivity(context);
    }

    @Override
    public void comment(Context context) {
        gotoLoginActivity(context);
    }

    private void gotoLoginActivity(Context context) {
        Intent intent = new Intent(context,LoginActivity.class);
        context.startActivity(intent);
    }
}

用户状态有两种:转发和评论。已登录状态下用户调用这两个函数会执行真正的转发和评论动作,未登录状态下则会直接跳转到登录界面。用户登录成功后转发和评论的行为也发生了改变。

状态机模式的优点:代码逻辑清晰,耦合性低,便于扩展;

状态机缺点:代码的实现类和对象个数比较多。

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值