状态模式(State)续谈

前面写了一片文章:状态模式(state)http://bestupon.iteye.com/blog/692913。各位JE好友提出了很多宝贵的意见和建议。尤其是“抛出异常的爱”。

关于红绿灯等状态之间的转换我的写法是:

 

package org.bestupon.dp.state.refactor;

/**
 * 
 * @author BestUpon
 * @email bestupon@foxmail.com
 * @date 2010-6-15下午05:21:15
 * @ask
 * @answer
 */
public abstract class Light implements LightState {

	@Override
public abstract void change(TrafficLight light, LightState nextState);
	protected void sleep(int second) {
		try {
			Thread.sleep(second);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 在重新改写之后客户端调用如下:

 

class Client {
	public static void main(String[] args) {

		TrafficLight trafficLight = new TrafficLight();
		LightState states[] = StateHolder.getStates();
		int index = 0;
		while (index != states.length) {
			trafficLight.change(trafficLight, states[index]);
//			trafficLight.change(trafficLight, states[index%2]);//取出下标为index mod 2 的那个状态
//			trafficLight.change(trafficLight, new YellowLight());// 每次重新创建一个对象
//			trafficLight.change(trafficLight,index == states.length - 1 ? states[0] : states[index + 1]);//取出下一个数组元素做状态
			index++;
			if (index == states.length)
				index = 0;
		}
	}
}

 可以方便的更改下一个状态是怎么样的!

对于老抛提出了如下写法:

 

enum Light{
    红灯(1000),黄灯(5000),绿灯(5000);    //顺序调整.
    int sleepping;
    private Light(int x) {
        this.sleepping = x ;        
    } 
    public Light change(){
        System.out.println(name());
        sleep();
        return next();
    }
	
    public Light next(){
        return values()[((ordinal()+1)%(values().length))];
    }
    public static void main(String[] args) {
		Light light = Light.红灯;
    	while(true){
			light = light.change();
		}
	}
    private void sleep() {
		try {
			Thread.sleep(this.sleepping);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 还有其他好友给出的代码,都让我前面写的: index == states.length - 1 ? states[0] : states[index + 1] 取出下一个元素的一种情况给误导了,

大家都认为是遍历数组就可以了!

对于“iaimstar”JEer,说的:

 

可能这也是比较正统的状态模式的实现,但是实际上,枚举和lz的状态模式都有些问题 

状态模式最大的特点是能在运行期间动态的改变行为,而作为状态的对象则不依赖于其他对象而独立变化。 

枚举的问题很明显,增加修改状态都很麻烦,而将状态切分成不同的类可以更灵活的添加和修改状态。 

lz的状态模式我则觉得有些问题,状态模式的好处正是状态对象本身可以通过context独立转换,比如,当红灯结束的时候绿灯亮起,状态的迁移由状态本身来完成。 

而lz的状态模式更像是chain,通过预先定义好下一个chain(state)在执行已有的状态迁移逻辑,个人觉得并不能算是动态的改变行为,反而有点画蛇添足,而且也没有state本身来指定nextstate来的灵活。

 

 个人认为:

客户端传递给的nexeState,虽然每次要指定给context,下一个状态是什么,这也利用了状态模式运行期间依靠动态的改变自身的状态,来决定自己的行为的特性。像“iaimstar”给出的应该是定向线路的话,个人觉得,指定next更像是随机线路,如果说一个是直线的话,那么另一个将是点集。或者其他,但是没有影响对象的行为,应为行为和状态是绑定在一起的,状态改变的话,行为必然是会变!

 

或许我的理解还有很大的问题!还望各位JEer指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值