状态模式

1.状态模式是什么

1.百度百科

状态模式(State Patten)允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类

2.维基百科

The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass.

The state pattern can be interpreted as a strategy pattern which is able to switch the current strategy through invocations of methods defined in the pattern's interface.

This pattern is used in computer programming to encapsulate varying behavior for the same object based on its internal state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements[1]:395 and thus improve maintainability.

3.lz理解

4.核心角色

抽象状态类(State) :状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。

具体状态类(ConcreteState) :具体状态,实现相关行为的具体状态类。

环境类(Context) :它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。

2.状态模式解决了什么问题

对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

灵活增加状态 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

简化了结构 能有效的将if/else等大块操作分别放入各个类中,让一个类只负责一个功能。遵循了单一职责原则。

减少对象数量 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

3.状态模式用法

判断目前此人是什么情绪

抽象状态类、抽象情绪类。能更改情绪

public interface Mood {

	void emotionalChanges(Person person);
}

具体状态类、平静、愤怒、高兴等情绪。

public class Normal implements Mood {

	@Override
	public void emotionalChanges(Person person) {
		if (person.getState() == 50) {
			System.out.println("心情平静");
		} else {
			person.setMood(new Happy());
			person.changeMood();
		}

	}

}

public class Angry implements Mood {

	@Override
	public void emotionalChanges(final Person person) {
		if(person.getState() < 50) {
			System.out.println("很生气");
		}else {
			person.setMood(new Normal());
			person.changeMood();
		}

	}

}

public class Happy implements Mood {

	@Override
	public void emotionalChanges(final Person person) {
		if (person.getState() > 50) {
			System.out.println("心情高兴");
		} else {
			person.setMood(new Angry());
			person.changeMood();
		}

	}

}

环境类、人。情绪的载体

public class Person {
	//状态
	private Mood mood;
	//心情指数
	private int state;

	public Person() {
		super();
		this.mood = new Normal();
		this.state = 50;
	}

	public Mood getMood() {
		return mood;
	}

	public void setMood(final Mood mood) {
		this.mood = mood;
	}


	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	public void changeMood() {
		mood.emotionalChanges(this);
	}
}

客户端测试

public class Client {

	public static void main(String[] args) {
		Person p = new Person();
    //老爸发了一拨奖金
		p.setState(70);
		p.changeMood();
	}
}

结果:

心情高兴

4.状态模式的问题

对象个数膨胀 状态模式的使用必然会增加类和对象的个数,如果使用不当将导致程序结构和代码的混乱。

业务逻辑复杂 由于状态模式的判断结构都是分布在各个状态具体类中。不能有效的判断出该状态代表的具体实现,业务逻辑理解难度陡然则增加。

开闭支持不好 添加新的状态模式的时候需要更改其他状态中的跳转方式,否则无法切换到新状态。

5.状态模式总结

应用场景:
1、对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为。
2、代码中包含大量与对象状态有关的条件语句,这些条件语句的出现,会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,使客户类与类库之间的耦合增强。在这些条件语句中包含了对象的行为,而且这些条件对应于对象的各种状态。

碎碎念:
状态模式我觉得其优点是确实能将项目的if/else结构用多态的方式替换掉,将臃肿的代码简化为一个一个封装独立的功能呢修改某一状态下的代码并不会影响其他代码。对于增加状态这个事情我觉得其实状态模式并不适合频繁增加状态的场合。应为增加一个新状态必然有一个旧装填需要修改,这么修改容易影响到原始代码。状态模式是将if/else 的膨胀作为变化封装起来从而达到推展容易,修改if/else中的代码也不会影响到其他装填的代码。

引用

http://blog.csdn.net/seu_calvin/article/details/52779282

posted @ 2018-02-09 17:32  枫飘雪落  阅读(205)  评论(0编辑  收藏  举报