一、概念
在状态模式中,对象的行为是由当前对象所处的状态来决定的,也就是说不同的状态会对应不同的行为,就像电灯对应的有开、关两个状态,开的状态中电流是通的,关的状态中电流是断开的;状态模式把对象的行为包装在不同的状态对象中,每个状态对象都有一个共同的抽象状态基类。意图是让一个对象在其内部状态改变时其行为也随着改变。
二、什么时候用到状态模式
在代码中需要大量与对象状态有关的条件语句,这时如果需求中多加了一种状态则需要添加多一个分支语句,需要修改原来的代码,违反了开放封闭原则,也容易造成漏改导致代码逻辑错误的情况下就可以使用状态模式,状态模式将每一个条件分支放入一个独立的类中,将对象自身的状态作为一个对象,这对象不依赖于其他对象而独立变化,当需要增加多一种状态时只需要继承状态的接口类实现对应的方法即可。
三、简单示例
这里模仿一个淘宝购物的情景,在淘宝中,当你点击一件商品的添加到购物车时,应用会根据你当前的状态执行相应的方法,如果是未登陆的状态,则跳转到登陆界面,如果是已登录状态,则把商品添加到购物车。
状态模式中的Context角色,用户的操作对象以及状态管理对象
**
* Created by huangzhebin on 16/5/16.
*/
public class LoginContext {
State state = new LogoutState();
static LoginContext loginContext = new LoginContext();
private LoginContext() {
}
public static LoginContext getLoginContext() {
return loginContext;
}
public void setState(State state) {
this.state = state;
}
public void add2ShoppingCar(Context context) {
state.add2ShoppingCar(context);
}
}
状态接口类
/**
* Created by huangzhebin on 16/5/16.
*/
public interface State {
public void add2ShoppingCar(Context context);
}
登录状态
/**
* Created by huangzhebin on 16/5/16.
*/
public class LoginedState implements State {
@Override
public void add2ShoppingCar(Context context) {
Toast.makeText(context, "已添加到购物车", Toast.LENGTH_SHORT).show();
}
}
未登陆状态
/**
* Created by huangzhebin on 16/5/16.
*/
public class LogoutState implements State{
@Override
public void add2ShoppingCar(Context context) {
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
}
}
点击添加按钮时进行的操作
public void add(View v) {
LoginContext.getLoginContext().add2ShoppingCar(this);
}
登陆后设置登陆状态
public void login(View v) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
LoginContext.getLoginContext().setState(new LoginedState());
finish();
}