状态模式
状态模式表示事物的行为是由状态来决定的,不同的状态有不同的行为。
状态模式的作用就是,当对象的内部状态发生改变时,其行为也随之改变。
举例说明:
1.我们的电视遥控器可以控制电视的开关,当打开开关时,可以点击音量,下一频道等操作,当关闭开关时,按住这些按钮是不会有任何响应行为的,也就是说电视的开关状态不同,其行为也不同.
2.我们的很多app都需要登录,如果没有登录就不能做一些操作.比如:玩微博时,如果没有登录,我们只能浏览一些资讯,只能看,但是不能转发,评论等,需要登录才能实现这些操作.这也是一个由状态反映行为的例子.
实现
非状态模式来实现
如果不用状态模式,我们来模拟实现下电视机遥控的例子,
class TVController {
private int mState = 0;
private final int TV_State_OFF = 0;
private final int TV_State_ON = 1;
public TVController() {
// 默认是关闭状态
setState(TV_State_OFF);
}
public void setState(int state) {
mState = state;
if (mState == 0) {
System.out.println("电视机关闭");
}else if (mState == 1) {
System.out.println("电视机打开");
}
}
public void nextTV() {
if (mState == TV_State_ON) {
System.out.println("下一个频道");
} else {
System.out.println("啥都不做");
}
}
public void addVoice() {
if (mState == TV_State_ON) {
System.out.println("增大音量");
} else {
System.out.println("啥都不做");
}
}
}
public class Test {
public static void main(String[] args) {
TVController t = new TVController();
t.nextTV();
t.addVoice();
t.setState(1);
t.nextTV();
t.addVoice();
}
}
电视机关闭
啥都不做
啥都不做
电视机打开
下一个频道
增大音量
可以看到,用上面的方式实现会做很多if,else的判断,如果有很多状态的话,这种无谓的判断就更多,代码可读性差,而且影响性能!
状态模式实现
下面看下这套模式下的类组成:
1.公共的抽象接口State,定义一组接口,标识状态的行为
2.State的具体实现类,表示不同的状态,定义具体的行为
3.状态管理类Controller(也叫Context),提供用户的调用接口
// 状态接口,定义行为
public interface TVState {
void nextTV();
void preTV();
void addVoice();
void deVoice();
}
// 具体状态类,有自己的操作实现
public class PowerOffState implements TVState{
public void nextTV() {
System.out.println("啥也不做");
}
public void preTV() {
System.out.println("啥也不做");
}
public void addVoice() {
System.out.println("啥也不做");
}
public void deVoice() {
System.out.println("啥也不做");
}
}
public class PowerOnState implements TVState{
public void nextTV() {
System.out.println("下一个频道");
}
public void preTV() {
System.out.println("上一个频道");
}
public void addVoice() {
System.out.println("增加音量");
}
public void deVoice() {
System.out.println("减小音量");
}
// 给用户操作调用的类,维护一个State基类,多态实现
public interface PowerController {
void powerOn();
void powerOff();
}
public class TvController implements PowerController{
TVState mTvState;
public void setState(TVState state) {
mTvState = state;
}
public void powerOn() {
setState(new PowerOnState());
}
public void powerOff() {
setState(new PowerOffState());
}
public void nextTV() {
mTvState.nextTV();
}
public void preTV() {
mTvState.preTV();
}
public void addVoice() {
mTvState.addVoice();
}
public void deVoice() {
mTvState.deVoice();
}
}
}
public class Test {
public static void main(String[] args) {
TvController t = new TvController();
t.setState(new PowerOffState());
t.nextTV();
t.preTV();
t.addVoice();
t.deVoice();
t.setState(new PowerOnState());
t.nextTV();
t.preTV();
t.addVoice();
t.deVoice();
}
}
啥也不做
啥也不做
啥也不做
啥也不做
下一个频道
上一个频道
增加音量
减小音量
这样就实现了状态模式.同样的,对于微博的注册登录也是这样的实现.
使用的好处与优点
好处
状态模式用多态实现了if else的功能判断,减少了这种逻辑的判断操作,保证程序的扩展性与可维护性.
缺点
要说缺点就是增加了很多类,和对象的个数
总结
在实际的开发中,要考虑所处的情景以及需要解决的问题,只有符合特定的场景才使用相应的模式.