状态模式的应用

07-04-26 casey
         

看了2天文章,还是搞不太明白如何应用状态模式

例如:考生有3种状态:等待考试,正在考试,已交卷

每个状态的变化都需要一些跟状态本身无关的额外操作,例如更新考试时间,计算成绩,写入数据库等;而这些操作是否执行,取决于状态是否转换成功

考生Student

假设State接口有如下两个方法

startExam(Student stu)

submitExam(Student stu)

有3个具体的State:StateBefore,StateIng,StateSubmit

那么StateIng

void submitExam(Student stu){

stu.setState(new StateSubmit(stu));

}

假设此时还应该调用Student的calScore操作,这个操作应该放到什么地方呢?如果放到此方法里,State和Student的耦合度是不是太高了,而且似乎State本身应该只关心当前状态和下一个状态,对Student的其他数据不应该关心,对么?

不知道我描述清楚了没有

         

banq
2007-05-10 17:42

你的State接口有两个方法startExam(Student stu)和submitExam(Student stu)抽象得不精确。

state接口应该是两个基本方法:获得当前状态;获得到下一个状态(包括转换规则)

casey
2007-05-12 17:17

不太明白,怎么会只有2个基本方法呢,方法的个数应该取决于业务逻辑

public interface State {

public void startExam(Student stu) throws ExamException;

public void submitExam(Student stu) throws ExamException;

}

//-----------------------------------

public class Student {

private State state;

public void calScore() {

// 计算成绩

}

public void setState(State state) {

}

}

//--------------------------------------

public class StateNotStart implements State {

public void startExam(Student stu) throws ExamException {

synchronized (stu) {

stu.setState(new StateExaming());

}

}

public void submitExam(Student stu) throws ExamException {

throw new ExamException("Wrong State");

}

}

//----------------------------------------

public class StateExaming implements State {

public void startExam(Student stu) throws ExamException {

throw new ExamException("Wrong State");

}

public void submitExam(Student stu) throws ExamException {

synchronized (stu) {

stu.calScore();

stu.setState(new StateFinished());

}

}

}

//-------------------------------

public class StateFinished implements State {

public void startExam(Student stu) throws ExamException {

throw new ExamException("Wrong State");

}

public void submitExam(Student stu) throws ExamException {

throw new ExamException("Wrong State");

}

}

还是State和Student耦合,不过觉得就应该这样的说,期待banq指教

banq
2007-05-14 09:26

>方法的个数应该取决于业务逻辑

这个认识我认为有问题的,状态模式作为一个专门设计模式,它是和业务不太有关系的模式,它是为专门解决状态这个核心问题而产生的模式,至于业务逻辑可以独立到外面和状态模式协同合作。

这里面有一个细分问题,要将业务逻辑中的状态state控制分离出来移植到状态模式中实现。

casey
2007-05-14 09:33

banq大师,能不能说得具体点,具体到这个例子该如何设计?

比如现在状态要增加一个“被取消考试资格”,相对应的业务逻辑是被取消考试资格,我的理解是State接口要多一个cancelExam方法,所有的State实现都应对该方法作处理。这就是我说得方法的个数取决于业务逻辑

真的不知道该如何:业务逻辑可以独立到外面和状态模式协同合作

还有你说得:状态模式作为一个专门设计模式,它是和业务不太有关系的模式,那要他还有什么意义呢?不解阿

谢谢

2Go 1 2 下一页