使用场景如下:
酒店系统中,房间的状态变化:
-
已预定
-
已入住
-
空闲
状态模式核心是:
- 用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题
接下来用代码来实现以上酒店的场景:
1),创建状态的接口类
/**酒店状态接口类
* @author 晓电脑
*/
public interface State {
void changeStatus();
}
2),创建酒店空闲状态的类继承State
/**酒店空闲状态
* @author 晓电脑
*/
public class FreeState implements State {
@Override
public void changeStatus() {
System.out.println("空闲状态");
}
}
3),创建酒店房间已预订类,继承State
/**预定状态
* @author 晓电脑
*/
public class ReserveState implements State {
@Override
public void changeStatus() {
System.out.println("预定状态");
}
}
4),创建酒店入住状态.继承Strate
/**入住状态
* @author 晓电脑
*/
public class CheckInState implements State {
@Override
public void changeStatus() {
System.out.println("入住状态");
}
}
5),创建HomeContest来改变房间状态
/**房间对象类
* @author 晓电脑
*/
public class HomeContest {
//如果是银行系统,这个contest类就是账号 根据金额不同,切换不同的状态
private State state;
public void setState(State state) {
System.out.println("修改房间的状态");
this.state = state;
state.changeStatus();
}
}
6),创建客户端进行测试
/**测试客户端
* @author 晓电脑
*/
public class Client {
public static void main (String[] args) {
HomeContest contest = new HomeContest();
//已预订
contest.setState(new ReserveState());
//已入住
contest.setState(new CheckInState());
}
}
运行如下
uml类图如下
开发中常见的场景:
- 银行系统中账号状态管理
- OA系统中公文状态的管理
- 酒店系统中,房间状态的管理
- 线程对象各状态之间的切换
状态模式和策略模式有很多相同点与不同点:
相同点
- 添加新的策略/新的状态,都不需要改变已有的代码,添加新的策略/状态的实现类即可
- 都符合开闭原则
- 它们都依赖子类去实现相关行为
- 状态设计模式十一不同的状态封装不同的行为,策略设计模式是以不同的策略封装不同的行为
不同点:
- 状态模式是在帮助一个类在不同的状态下显示不同的行为。 策略模式是封装一组相关的算法,它允许Client在运行时使用可互换的行为。
- 状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用,通过Context中分离出策略或方法,我们可以重用它。
- 状态模式中,每个Cojntext的引用,来实现状态转移,但是每个策略都不持有Context的引用,它们只是被Context使用。
- 状态模式是由Context/状态自己来改变用户的状态,而策略模式是由Client来改变行为