假如现在有一个这样的问题, 如果一个集合存储A,B,C的对象(B继承了A,C继承了B),现在需要对 这个集合进行遍历,根据取出来的元素不同对待,那么我们应该怎么做呢。
我们一般都会用if/else语句进行判断处理,如下:
public static void main(String[] args) throws IOException,Exception {
ArrayList arrayList = new ArrayList();
arrayList.add(new A());
arrayList.add(new B());
arrayList.add(new C());
arrayList.add(new Object());
for(Object object : arrayList){
if(object instanceof C){
System.out.println("遍历到了C的对象\n");
} else{
if(object instanceof B){
System.out.println("遍历到了B的对象\n");
} else{
if(object instanceof A){
System.out.println("遍历到了A的对象\n");
} else {
System.out.println("该对象既不是A的对象也不是A的子类的对象\n");
}
}
}
}
}
下面我们用状态模式来实现功能:
/**
* 状态类
* 本次功能相对简单,于是将State由抽象类转变为了接口
*/
public interface State {
/**
* 对对象进行判断
* @param object
*/
void judge(Object object);
}
public class StateA implements State {
/**
* 判断是否为A的对象
* @param object
*/
@Override
public void judge(Object object) {
if(object instanceof A){
System.out.println("遍历到了A的对象\n");
}
else System.out.println("该对象既不是A的对象也不是A的子类的对象\n");
}
}
public class StateB implements State {
/**
* 判断是否为B的对象,不是则交给StateA判断
* @param object
*/
@Override
public void judge(Object object) {
if(object instanceof B){
System.out.println("遍历到了B的对象\n");
}
else (new StateA()).judge(object);
}
}
public class StateC implements State{
/**
* 判断是否为C的对象,不是则交给StateB判断
* @param object
*/
@Override
public void judge(Object object) {
if(object instanceof C){
System.out.println("遍历到了C的对象\n");
}
else (new StateB()).judge(object);
}
}
public class JudgeState {
State state;
//如果添加新的状态StateD可以改为StateD,或者使用反射进行初始化
public JudgeState(){
this.state = new StateC();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void Judge(Object object){
state.judge(object);
}
}
public static void main(String[] args) throws IOException,Exception {
ArrayList arrayList = new ArrayList();
arrayList.add(new A());
arrayList.add(new B());
arrayList.add(new C());
arrayList.add(new Object());
JudgeState judgeState = new JudgeState();
for(Object object : arrayList){
judgeState.Judge(object);
}
}
两次运行结果如下:
首先我们对比一下两个代码:利用if/else进行判断非常简单,但是代码看起来非常的臃肿,代码的可读性下降,不利于修改 。并且我们如果多加一个D的对象,就要多加一个if/else判断,也就说与开闭原则相违背了,而状态模式只需要多加一个StateD类。 状态模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}