我们在之前的项目中创建了五个与学生相关的类。Student类是一个抽象父类,用于保存学生的id等基本信息。Freshman类、Sophomore类、Junior类和Senior类继承自Student类,分别表示大一、大二、大三和大四的学生。
在本项目中,我们将模拟各个年级学生在学年开始和学年结束时,需要完成的任务。在本项目中,我们将使用状态模式和享元模式来实现各年级学生的状态以及状态之间的转换。
首先,我们使用状态模式来模拟各个年级学生的状态。我们在包com.littlewaterdrop.state中定义一个新的接口StudentState;它有两个成员方法preEnter()和postLeave()。这两个方法都接收一个Student对象参数,无返回值。
public interface StudentState {
void preEnter(Student theStudent);
void postLeave(Student theStudent);
}
然后,我们实现四个类FreshmanState类、SophomoreState类、JuniorState类和SeniorState类。它们了实现StudentState接口。它们的preEnter()和postLeave()方法暂时留空。
我们在com.littlewaterdrop.bean.Student类中添加一个私有成员变量state和它的getter和setter方法。
在Freshman类、Sophomore类、Junior类和Senior类的构造函数中,直接创建对应状态的对象,并直接将该对象传入Student类的构造函数,初始化成员变量state。例如,Freshman的构造函数可以这样实现。
public class Freshman() extends Student {
public Freshman(String id, String name, Integer age, String major) {
super(id, name, age, major, StudentStateFactory.getFreshmanState()); // 我们将在步骤三中介绍如何创建state对象
}
}
我们在com.littlewaterdrop.state包中创建一个新类StudentStateFactory,用于创建State对象。它有四个公有静态方法,分别用于创建FreshmanState、SophomoreState、JuniorState和SeniorState对象。因为每个Freshman对象使用的FreshmanState对象都是相同的,我们没有必要为每个Freshman对象都创建一个FreshmanState对象。相同的情况也适用于Sophomore、Junior和Senior对象上。
因此,我们在这里使用享元模式。我们要求StateFactory最多可为每一个State类创建一个对象,从而实现对象共享的目的。
public static FreshmanState getFreshmanState();
public static SophomoreState getSophomoreState();
public static JuniorState getJuniorState();
public static SeniorState getSeniorState();
在Student类的setState()方法中,当状态发生变化时,我们需要触发事件。因此,我们需要如下修改该方法的实现。
public class Student {
public void setState (StudentState state) {
this.state.postLeave(this);
state.preEnter(this);
this.state = state;
}
}
最后,我们实现各个状态下的事件方法。在preEnter()方法和postLeave()方法中要求各自打印一个字符串,表示进入和离开该状态。例如,FreshmanState可以按照如下实现。其他类的实现以此类推。
public class FreshmanState implements StudentState {
@Override
public void preEnter(Student theStudent) {
System.out.println(theStudent.getName() + " is entering the Freshman state.");
}
@Override
public void postLeave(Student theStudent) {
System.out.println(theStudent.getName() + " is leaving the Freshman state.");
}
}