利用状态模式去除多个if/else

zhy

发布于 2020.03.10 19:59 阅读 2603 评论 2

    假如现在有一个这样的问题, 如果一个集合存储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类。 状态模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。