状态模式
状态模式
状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
State类,抽象状态类,定义一个接口以封装与 Context 的一个特定状态相关的行为。
Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
抽象状态类
abstract class State {
public abstract void handle(Context context);
}
具体状态类
//具体状态类A
class ConcreteStateA extends State
{
public void handle(Context context) {
// 处理并设置新的状态
context.setState(new ConcreteStateB());
}
}
//具体状态类B
class ConcreteStateB extends State
{
public void handle(Context context) {
// 处理并设置新的状态
context.setState(new ConcreteStateA());
}
}
Context类
// 上下文
class Context {
// 包含一个状态
private State state;
public Context(State state){
this.state = state;
}
//可读写的状态属性,用于读取当前状态和设置新状态
public State getState(){
return this.state;
}
public void setState(State value){
this.state = value;
System.out.println("当前状态:" + this.state.getClass().getName());
}
public void request(){
// 对请求进行处理,并设置下一个状态
this.state.handle(this);
}
}
客户端
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
// 新建一个context实例,并设置一个状态
Context c = new Context(new ConcreteStateA());
// 根据状态,对请求做出不同的行为,处理完成后,进行状态转换。
c.request();
c.request();
c.request();
c.request();
System.out.println();
System.out.println("**********************************************");
}
}
在上面的Context类中,包含了一个状态对象,Context在根据不同的状态去执行不同的行为,在具体状态类中,在处理完成请求后,又改变了Context类中的状态。不断的请求,不断的改变状态。
状态模式的好处和用处
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来,每一个状态对应了一个状态类。
将特定的状态相关的行为都放在一个对象中,由于每一种状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
这样做的目的就是消除庞大的判断状态的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
何时考虑使用状态模式?
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
工作状态
根据不同的时间段,工作的状态不同。针对每一个状态,定义不同的行为。把每一个状态相关的行为都定义在同一个对象中。在抽象状态类中有一个 写程序的行为,在状态子类中,根据状态给出不同的实现。在状态子类中,根据条件完成状态的转换。
抽象状态类
abstract class State {
// 定义每一个状态中所需要实现的行为
public abstract void writeProgram(Work w);
}
具体的状态类
//上午工作状态
class ForenoonState extends State {
public void writeProgram (Work w) {
// 根据时间来判断,状态的转换
if (w.getHour() < 12) {
System.out.println("当前时间:"+ w.getHour() +"点 上午工作,精神百倍");
}
else {
w.setState(new NoonState());
w.writeProgram();
}
}
}
//中午工作状态
class NoonState extends State {
public void writeProgram (Work w) {
if (w.getHour() < 13) {
System.out.println("当前时间:"+ w.getHour() +"点 饿了,午饭;犯困,午休。");
}
else {
// 设置新的状态
w.setState(new AfternoonState());
w.writeProgram();
}
}
}
//下午工作状态
class AfternoonState extends State {
public void writeProgram (Work w) {
if (w.getHour() < 17) {
System.out.println("当前时间:"+ w.getHour() +"点 下午状态还不错,继续努力");
}
else {
// 设置新的状态
w.setState(new EveningState());
w.writeProgram();
}
}
}
//晚间工作状态
class EveningState extends State {
public void writeProgram(Work w)
{
// 晚上 17点后,根据工作完成的属性,进行状态的转换
if (w.getWorkFinished())
{
// 设置新的状态
w.setState(new RestState());
w.writeProgram();
}
else
{
if (w.getHour() < 21) {
System.out.println("当前时间:"+ w.getHour() +"点 加班哦,疲累之极");
}
else {
w.setState(new SleepingState());
w.writeProgram();
}
}
}
}
//睡眠状态
class SleepingState extends State {
public void writeProgram(Work w) {
System.out.println("当前时间:"+ w.getHour() +"点 不行了,睡着了。");
}
}
//下班休息状态
class RestState extends State {
public void writeProgram(Work w) {
System.out.println("当前时间:"+ w.getHour() +"点 下班回家了");
}
}
工作类
class Work {
// 当前的状态
private State current;
public Work(){
current = new ForenoonState();
}
//设置状态
public void setState(State value) {
this.current = value;
}
//写代码的状态
public void writeProgram() {
this.current.writeProgram(this);
}
//当前的钟点,根据时间,进行状态的转换
private int hour;
public int getHour(){
return this.hour;
}
public void setHour(int value){
this.hour = value;
}
//当前工作是否完成
// 根据工作是否完成来进行状态的转换
private boolean workFinished = false;
public boolean getWorkFinished(){
return this.workFinished;
}
public void setWorkFinished(boolean value){
this.workFinished = value;
}
}
客户端
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.setHour(9);
emergencyProjects.writeProgram();
emergencyProjects.setHour(10);
emergencyProjects.writeProgram();
emergencyProjects.setHour(12);
emergencyProjects.writeProgram();
emergencyProjects.setHour(13);
emergencyProjects.writeProgram();
emergencyProjects.setHour(14);
emergencyProjects.writeProgram();
emergencyProjects.setHour(17);
emergencyProjects.setWorkFinished(false);
//emergencyProjects.setWorkFinished(true);
emergencyProjects.writeProgram();
emergencyProjects.setHour(19);
emergencyProjects.writeProgram();
emergencyProjects.setHour(22);
emergencyProjects.writeProgram();
System.out.println();
System.out.println("**********************************************");
}
}