面向对象设计其实就是希望做到代码的责任分解
1.定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
- 主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转义到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
2.优点
- 将于特定状态相关的行为局部化,并且将不同状态的行为分割开来。
- 将待定的状态相关的行为都放入一个对象,由于所有的与状态相关的代码都存在与某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。减少了类与类、状态与状态之间的一拉。
- 消除了庞大的条件分治语句。
- 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为的时候,考虑使用状态模式。
3.以工作状态为例,理解状态模式
比如我们写代码的行为,取决于我们的身体状态。 身体状态的转变,行为也跟着变化。
(1)工作类,会根据不同的身体状态发生变化
package com.state;
public class Work {
private State current;
public Work(){
current=new ForenoonState(); //工作状态初始化为最早的状态
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private int hour; //状态转换的依据
private boolean finish=false; //是否能下班的依据
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
public void WriteProgram(){
current.WriteProgram(this);
}
}
(2)抽象状态类
package com.state;
public abstract class State {
public abstract void WriteProgram(Work w);
}
(3)早上状态类
package com.state;
//上午的工作状态
public class ForenoonState extends State{
@Override
public void WriteProgram(Work w) {
if(w.getHour()<12){
System.out.println(w.getHour()+" 上午工作,精神百倍!");
}else{
//超过12点,就转入中午工作状态
w.setCurrent(new NoonState());
w.WriteProgram();
}
}
}
(2)中午状态类
package com.state;
public class NoonState extends State{
@Override
public void WriteProgram(Work w) {
if(w.getHour()<13){
System.out.println(w.getHour()+" 饿了,午饭;困了午睡。");
}else{
w.setCurrent(new AfternoonState());
w.WriteProgram();
}
}
}
(3)下午状态类
package com.state;
public class AfternoonState extends State{
@Override
public void WriteProgram(Work w) {
if(w.getHour()<17){
System.out.println(w.getHour()+" 下午状态不错,坚持!");
}else{
w.setCurrent(new EveningState()); //状态转到晚上
w.WriteProgram();
}
}
}
(4)晚上状态类
package com.state;
public class EveningState extends State{
@Override
public void WriteProgram(Work w) {
if(w.isFinish()){
w.setCurrent(new RestState()); //完成任务,下班
w.WriteProgram();
}else{
if(w.getHour()<21){
System.out.println(w.getHour()+" 加班,非常累!");
}
else{
w.setCurrent(new SleepingState());
w.WriteProgram(); //状态转到睡眠
}
}
}
}
(5)下班状态类
package com.state;
public class RestState extends State{
@Override
public void WriteProgram(Work w) {
System.out.println(w.getHour()+" 下班了!");
}
}
(6)睡觉状态类
package com.state;
public class SleepingState extends State{
@Override
public void WriteProgram(Work w) {
System.out.println(w.getHour()+" 睡觉。");
}
}
(7)客户端类
package com.state;
public class Client {
public static void main(String[] args) {
Work emergencyProjects=new Work();
emergencyProjects.setHour(9);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(12);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(13);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(14);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(17);
emergencyProjects.WriteProgram();
emergencyProjects.setFinish(true);
//emergencyProjects.setFinish(false);
emergencyProjects.setHour(19);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(22);
emergencyProjects.WriteProgram();
}
}
(8)执行结果
9 上午工作,精神百倍!
12 饿了,午饭;困了午睡。
13 下午状态不错,坚持!
14 下午状态不错,坚持!
17 加班,非常累!
19 下班了!
22 下班了!