允许一个对象内部状态改变时改变其行为,使得这个对象看起来改变了其类。
允许一个对象内部状态改变时改变其行为,使得这个对象看起来改变了其类。
如果一个对象的行为取决于其内部的一个或多个动态变化的属性的值,那么这些属性被称之为状态(state),这类对象被称之为有状态的对象(stateful),行为与状态间的转换关系可以由状态转换图体现,如进程间的状态转换关系
如果将进程视为一个对象,这个对象就拥有新建,就绪,运行,阻塞,终止五种状态,对象的具体行为就会由状态决定。如果直接使用多个if else
来描述这个状态,就违反了开闭原则,所以引入了状态模式,状态模式允许一个对象内部状态改变时改变其行为,使得这个对象看起来改变了其类。
状态模式包含三部分:
setState()
方法,用来修改当前状态;最后上下文还要包含一个或多个行为方法,这些行为方法是开放给客户端使用的,上下文中的行为方法应该是调用具体状态对象对应的行为方法。例:
投简历找工作的过程中,存在三个状态:
首先建立抽象状态类:
package pers.junebao.state.recruitment;
public interface IState {
/**
* 每个具体状态类应该实现的行为(方法)
* @param context 当前的上下文对象,方便在具体实现中修改状态
*/
void header(Context context);
}
header()
是在某个状态下,系统应该做的事(这个例子里应该分成两个:每个状态公司系统做的事和每个状态展示给应聘者的东西)建立上下文类
package pers.junebao.state.recruitment;
public class Context {
// 初始状态为 新投递
private IState state = new NewDeliveryStare();
protected void setState(IState state) {
this.state = state;
}
// 展示给客户端的方法,其实内部调用状态类的header方法
public void header(){
this.state.header(this);
}
}
实现抽象状态类IState
完成具体状态类
新投递状态
package pers.junebao.state.recruitment;
import java.util.Scanner;
public class NewDeliveryStare implements IState {
private boolean resumeApproval(){
System.out.println("简历是否合格(Y/N):");
String input = new Scanner(System.in).next();
return "Y".equals(input) || "y".equals(input);
}
@Override
public void header(Context context) {
if(resumeApproval()){
System.out.println("恭喜通过简历评估,请等待面试...");
context.setState(new InterviewState());
} else {
System.out.println("简历评估未通过!");
context.setState(new RefuseState());
}
}
}
面试状态
package pers.junebao.state.recruitment;
import java.util.Scanner;
public class InterviewState implements IState {
private boolean interview(){
System.out.println("面试是否合格(Y/N):");
String input = new Scanner(System.in).next();
return "Y".equals(input) || "y".equals(input);
}
@Override
public void header(Context context) {
if(interview()){
System.out.println("恭喜通过面试,即将发放offer!!");
context.setState(new PassState());
} else {
System.out.println("未能通过面试!!");
context.setState(new RefuseState());
}
}
}
通过状态
package pers.junebao.state.recruitment;
public class PassState implements IState {
@Override
public void header(Context context) {
System.out.println("恭喜您已通过所有考核!!!");
}
}
回绝状态
package pers.junebao.state.recruitment;
public class RefuseState implements IState {
@Override
public void header(Context context) {
System.out.println("已回绝!!");
}
}
客户端:
package pers.junebao.state.recruitment;
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.header();
context.header();
context.header();
}
}
运行结果:
适用场景:
优点:
if else
,提高了代码可读性和可拓展性,一定程度上符合开闭原则。缺点:
状态可被视为策略的扩展。 两者都基于组合机制: 它们都通过将部分工作委派给 “帮手” 对象来改变其在不同情景下的行为。 策略使得这些对象相互之间完全独立, 它们不知道其他对象的存在。 但状态模式没有限制具体状态之间的依赖, 且允许它们自行改变在不同情景下的状态。
共同点:
if else
不同点: