引言
上一节我们说了策略模式。这一节我们讲讲策略模式的双胞胎弟弟:状态模式,这个模式大家可能不常见,也不常用,但是我们还是需要了解一下。
示例地址
依然是类图
image在看定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来就是改变了其类。
使用场景
1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
2. 代码中包含大量与对象状态有关的条件语句,例如,一个操作中含有庞大的多分支语句(if-else或者switch-case),且这些分支依赖于该对象的状态。
状态模式的作用
将每一个条件分支放入一个独立的类中,这是的你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化,这样通过多态来去除过多的、重复的if-else等分支语句。
状态模式的示例
我们上初中的时候都学过物理,知道液化、升华、气化,大自然的水也有这三种状态固体、液体、气体,不同的状态有不同的表现形式,固态是冰,液态是水,气态就是水蒸气了。
1. 定义一个状态接口
/**
* 水的状态
*
* @author 512573717@qq.com
* @created 2018/7/12 下午4:15.
*/
public interface IState {
// 什么形状
void shape();
// 什么用途
void use();
}
2. 各种状态的实现
/**
* 固体
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:07.
*/
public class IceState implements IState {
@Override
public void shape() {
System.out.println("这是0度以下的水 固体的");
}
@Override
public void use() {
System.out.println("当前用途:可以用来存储蔬菜,保鲜的作用");
}
}
/**
* 液体
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:11.
*/
public class FluidState implements IState {
@Override
public void shape() {
System.out.println("这是0度到100之间的水 液体的");
}
@Override
public void use() {
System.out.println("当前用途:洗澡、浇树");
}
}
/**
* 气体
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:10.
*/
public class GasState implements IState {
@Override
public void shape() {
System.out.println("这是100度以上的水 气体的");
}
@Override
public void use() {
System.out.println("当前用途:用来真桑拿、食品等");
}
}
3. 状态管理类
/**
* 状态管理类
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:12.
*/
public class ClientContext {
private IState mIState = new IceState();
private static volatile ClientContext mClientContext;
private ClientContext() {
}
public static ClientContext getInstance() {
if (null == mClientContext) {
synchronized (ClientContext.class) {
if (null == mClientContext) {
mClientContext = new ClientContext();
}
}
}
return mClientContext;
}
public void setIState(IState IState) {
mIState = IState;
}
public void use() {
mIState.use();
}
public void shape() {
mIState.shape();
}
}
4. Client使用
// 默认是固态的水
ClientContext.getInstance().use();
//液态的水
ClientContext.getInstance().setIState(new FluidState());
ClientContext.getInstance().use();
// 气态
ClientContext.getInstance().setIState(new GasState());
ClientContext.getInstance().use();
总结
状态模式主要是避免代码膨胀,同时保证程序的扩展性和维护性。
策略模式与状态模式的区别
策略模式:封装一系列平行且复杂多变的实现方式。
状态模式:实现把对象的内在状态的变化封装起来,用外部行为来表现出来。
网友评论