定义: 当一个对象内在状态改变时允许改变行为,这个对象像是改变了其类型。状态模式是一种行为型设计模式。
- 抽象状态角色 : 封装抽象行为的接口;
- 具体状态角色 : 实现一种状态下对应的具体行为;
- 环境角色 : 持有状态类的实例,返回当前状态并负责具体状态的切换,挺像一个管理器的嗷。
举个例子,一天有24小时,以每个小时为一种状态,记录每种状态下要做的事情:
//抽象状态,只有一个行为:查看当前在做的事情
public interface Day {
void LookDoSomething();
}
以下是具体状态,列举几个时间段:
//6点起床
public class Timer6 implements Day {
@Override
public void LookDoSomething() {
Log.d("tag", "起床,刷牙,洗脸,吃早餐");
}
}
//23点睡觉
public class Timer23 implements Day {
@Override
public void LookDoSomething() {
Log.d("tag", "睡觉");
}
}
//17点下班
public class Timer17 implements Day {
@Override
public void LookDoSomething() {
Log.d("tag", "下班");
}
}
等等,状态类太多,明白意思就好,接下来是环境类:
public class Diary {
private Day day;
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public void doSomthing(){
//other something
}
}
环境类持除了有状态类实例,并且能切换各种状态(一个set方法就够了)外,也可以根据具体业务添加一些其他的逻辑处理。另外,在多个地方使用环境类,会觉得麻烦,要创建多个实例时还可以使用单例模式,将环境类对象变成单例的。 最后使用形式:
Diary diary = new Diary();
diary.setDay(new Timer12());
diary.getDay().LookDoSomething();
//切换状态
diary.setDay(new Timer6());
diary.getDay().LookDoSomething();
//切换状态
diary.setDay(new Timer23());
diary.getDay().LookDoSomething();
应用场景:
- 行为跟随状态变化而改变并且状态较多时;
优点:
- 结构清晰
- 良好的封装性
缺点:
- 子类太多(状态类),管理复杂
小结
状态模式的核心在于封装。根据不同的状态响应不同的逻辑,由于封装性良好,看起来就像是由状态改变类型。其实在不使用这种模式下处理大量条件逻辑时是使用if else 或者switch。都是根据条件执行逻辑,但是使用设计模式替换了复杂冗长的条件判断语句,使程序更加容易维护。新增状态时只需要新增加新的子类到添加到这个状态系统中去,不需要修改其他的类。某种情况下状态模式就是条件、分支语句的代替者。