策略模式和状态模式虽然类图上很相似,但是运用的时候个人觉得有很大的区别.
状态模式:当一个对象的内在状态变化时允许改变起行为,这个对象看起来像是改变了其类。
状态模式主要突出了两个字:”改变”, 对!对象的状态决定了状态的行为,事物的本质决定了事物的行为,我们精神亢奋的时候,我们拼命的工作,我们拼命的工作就导致了我们身心疲惫,物品们身心疲惫就导致我们的行为是需要休息;从这里我们可以看出,事物的内在状态决定了事物所做出的行为,而事物的行为势必又会改变我们事物的状态,两者在不断的相互影响,然后实现状态的迁移和跃迁;
从这两点,我们可以看出策略模式和状态模式的应用场景有很大的不同:一个是封装一系列平行且复杂多变的实现方式,一个是实现把对象的内在状态的变化封装起来,用外部行为来表现出来;
状态模式类图如下:
状态模式:当一个对象的内在状态变化时允许改变起行为,这个对象看起来像是改变了其类。
下面的例子是员工每天工作的状态和行为。小时和工作是否完成 是状态,精神百倍,午休等是行为。
代码如下:
class Work {
private int hour = 9;
private boolean isWorkFinished;
private State state;
public Work(){
state = new MorningState();
}
public void writeProgram(){
state.WriteProgram(this);
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isWorkFinished() {
return isWorkFinished;
}
public void setWorkFinished(boolean isWorkFinished) {
this.isWorkFinished = isWorkFinished;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
abstract class State {
public abstract void WriteProgram(Work work);
}
class MorningState extends State {
public void WriteProgram(Work work) {
if(work.getHour() < 12){
System.out.println("当前时间为上午:"+work.getHour()+"点,精神百倍");
}else{
work.setState(new NoonState());
work.writeProgram();
}
}
}
class NoonState extends State {
public void WriteProgram(Work work) {
if(work.getHour() < 13){
System.out.println("当前时间为中午:"+work.getHour()+"点,午饭,午休");
}else{
work.setState(new AfterNoonState());
work.writeProgram();
}
}
}
class AfterNoonState extends State {
public void WriteProgram(Work work) {
if(work.getHour() < 17){
System.out.println("当前时间为下午:"+work.getHour()+"点,精神百倍,继续");
}else{
work.setState(new EveningState());
work.writeProgram();
}
}
}
class EveningState extends State {
public void WriteProgram(Work work) {
if(work.isWorkFinished()){
work.setState(new RestState());
work.writeProgram();
}else{
if(work.getHour() < 21){
System.out.println("当前时间为晚上:"+work.getHour()+"点,继续加班");
}else{
work.setState(new SleepState());
work.writeProgram();
}
}
}
}
class RestState extends State {
public void WriteProgram(Work work) {
System.out.println("当前时间为晚上:"+work.getHour()+"点,回家休息");
}
}
class SleepState extends State {
public void WriteProgram(Work work) {
System.out.println("当前时间为晚上:"+work.getHour()+"点,下班回家睡觉");
}
}
public class StateClient {
public static void main(String[] args) {
Work work = new Work();
work.setHour(9);
work.writeProgram();
work.setHour(12);
work.writeProgram();
work.setHour(14);
work.writeProgram();
work.setHour(18);
work.writeProgram();
//work.setWorkFinished(false);
work.setWorkFinished(true);
work.setHour(19);
work.writeProgram();
work.setHour(22);
work.writeProgram();
}
}
如果用普通思路去写,势必会多个if else再嵌套if else,那么方法势必会过长。方法过长是坏味道。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断转移到表示不同状态的一系列类中,可以把复杂判断简化。
当一个状态的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,可以考虑使用状态模式。
如果业务有多个状态,通常为一些枚举常量,状态的变化都是依靠大量的分支判断来实现,此时可以考虑将每一种业务状态定义为一个state的子类,这样这些对象就可以不依赖于其他对象
而独立变化了,哪天客户要改变需求,增加或减少业务状态或改变状态流程,都是不难的事。
策略模式 略