現在姜小碼有這樣一個需求,讓王小碼寫一個方法判斷一個學生該上什么學校。
王小碼2分鐘后就給出了代碼:
public class Person {
private int age;
public Person(int age) {
this.age = age;
}
public void printSchool() {
if (this.getAge() < 6) {
System.out.println("小于6歲不能上學!");
} else if (this.getAge() >=6 && this.getAge() < 11) {
System.out.println("該上小學了!");
} else if (this.getAge() >= 11 && this.getAge() < 15) {
System.out.println("該上初中了!");
} else if(this.getAge() >= 15 && this.getAge() < 19) {
System.out.println("該上高中了!");
} else if (this.getAge() >= 19) {
System.out.println("該上大學了!");
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
姜小碼很高興,并把王小碼打了一頓。
假如姜小碼又有新需求,判斷這個學生在上幾年級。總不能寫18個判斷分支吧。這種寫法很顯然破壞了單一職責原則,雖然下面要說到的狀態設計模式增加了復雜性,但是易于擴展,符合面向對象的設計原則。
狀態設計模式就是為了解決這類判斷分支過多的問題,達到責任分解的目的。
狀態設計模式將特定的狀態相關行為放入一個對象中,由于所有與狀態相關的代碼都在某個State中,所以通過定義新的子類可以很容易增加狀態和轉換。
改造后的代碼:
包結構
-state //狀態設計模式
-states
-AgeState.java //狀態抽象類
-PrimaryState.java //小學
-MiddleState.java //初中
-HighState.java //高中
-UniversityState.java //大學
-Person.java
-PersonTest.java
抽象狀態
public abstract class AgeState {
public abstract void judge(Person person);
}
小學狀態
public class PrimaryState extends AgeState {
@Override
public void judge(Person person) {
if (person.getAge() < 6) {
System.out.println("年紀太小不足6歲,不能上學!");
} else if (person.getAge() >= 6 && person.getAge() < 11) {
System.out.println("該上小學了!");
} else {
person.setAgeState(new MiddleState());
person.printSchool();
}
}
}
初中狀態
public class MiddleState extends AgeState {
@Override
public void judge(Person person) {
if (person.getAge() >= 11 && person.getAge() < 15) {
System.out.println("該上初中了!");
} else {
person.setAgeState(new HighState());
person.printSchool();
}
}
}
高中狀態
public class HighState extends AgeState {
@Override
public void judge(Person person) {
if (person.getAge() >= 15 && person.getAge() < 19) {
System.out.println("該上高中了!");
} else {
person.setAgeState(new UniversityState());
person.printSchool();
}
}
}
大學狀態
public class UniversityState extends AgeState {
@Override
public void judge(Person person) {
if (person.getAge() >= 19) {
System.out.println("該上大學了!");
}
}
}
Person類
public class Person {
private int age;
private AgeState ageState;
public void printSchool() {
this.ageState.judge(this);
}
public Person(int age) {
this.age = age;
this.ageState = new PrimaryState();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public AgeState getAgeState() {
return ageState;
}
public void setAgeState(AgeState ageState) {
this.ageState = ageState;
}
}
測試:
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person(12);
p1.printSchool();
Person p2 = new Person(18);
p2.printSchool();
Person p3 = new Person(3);
p3.printSchool();
Person p4 = new Person(23);
p4.printSchool();
}
}
測試輸出:
該上初中了!
該上高中了!
年紀太小不足6歲,不能上學!
該上大學了!
這樣改完,以后擴展個研究生,博士,博士后還是很容易的。