java状态机设计模式_设计模式之状态模式

此文介绍我理解的状态设计模式,这是行为模式的一种,在很多需求的场景,一个对象的行为依赖对象的状态,这种场景很多,而且这种状态是可能持续迭代的,这种需求我们一般会给对象一个状态标志然后if-else判断去实现业务逻辑,这样每次来个新的状态都要增加 if-else,这样非常不好维护,需要去修改原来的类,不满足开闭原则。我举个例子,一个人的状态有很多种,穷或则富,或则中产,或则小康。不同的状态做同样的事情的感觉肯定不一样,而且以后可能还会增加新的人的分类。怎么去扩展呢。

按照不用模式的写法,是这样的:

public class Person {

private String status;

private String name;

//setter getter

}

然后一个调用类,各种行为需要判断人的状态:

class StateAction {

private Person person;

public StateAction(Person person) {

this.person = person;

}

public void show() {

// 变化剧烈,不好维护

if (person.getStatus() == "穷") {

drive("自行车");

dress("旧衣服");

System.out.println("....");

System.out.println("很穷的各种");

} else if (person.getStatus() == "富") {

drive("豪车");

dress("皮大衣");

System.out.println("....");

System.out.println("各种炫富啊");

} else if (person.getStatus() == "中产") {

// 如果以后还有各种状态...累死了, Bad smell

// T A T

}

// else if

}

private void drive(String msg) {

System.out.println(this.person.getName() + "开" + msg);

}

private void live(String msg) {

System.out.println(this.person.getName() + "住" + msg);

}

private void dress(String msg) {

System.out.println(this.person.getName() + "穿" + msg);

}

}

// 调用方法

Person person = new Person("小马哥");

// 不用模式

person.setStatus("穷");

StateAction stateAction = new StateAction(person);

stateAction.show();

person.setStatus("富");

stateAction.show();

这个是很正常的思维方式,这样是不好的,添加if else不好维护而且StateAction这个类承担了过多的指责,具体的对象状态与类的行为绑定死了,一旦一个状态的行为改变了,只能去改原先的逻辑,如果能达到一个动态的对象与行为的组合是更灵活的一种方式,把状态与人的行为与分离出来。能够让不同状态的行为变化能够动态的组合。

分析这个场景下的稳定部分与不稳定的部分

稳定的行为:

人的行为,那就是都有drive, dress, live这几个方法

不稳定的部分:

不同状态下的行为不稳定,可能有很多种行为方式集合

以下用状态的模式重写这块:

/** * 状态模式,隔离状态的接口 * 这里描述了具体人的不同的状态 */

interface State {

void dress();

void drive();

void live();

}

/** * 抽象实现,传入person作为状态的上下文 * Person可以是抽象类,那样是不是就和桥模式非常像,可以动态组装两个维度的变化对象 * 这里主要演示人在不通状态下的不同行为,所以person为具体实现 */

abstract class AbstractPersonState implements State {

protected Person person;

/** * 传入上下文 *@param person */

public AbstractPersonState(Person person) {

this.person = person;

}

protected String getPersonName() {

return this.person.getName();

}

protected void print(String msg){

System.out.println(msg);

}

/** * 展示下生活状态 */

public void show() {

// 钩子方法

this.drive();

this.dress();

this.live();

}

}

/** * 穷人状态 */

class PoolPersonState extends AbstractPersonState implements State {

public PoolPersonState(Person person) {

super(person);

}

@Override

public void dress() {

print(getPersonName() + "穿旧衣服");

}

@Override

public void drive() {

print(getPersonName() + "开自行车");

}

@Override

public void live() {

print(getPersonName() + "住农民房");

}

}

/** * 富豪状态 */

class RichPersonState extends AbstractPersonState implements State {

public RichPersonState(Person person) {

super(person);

}

@Override

public void dress() {

print(getPersonName() + "穿皮大衣");

}

@Override

public void drive() {

print(getPersonName() + "开豪车啊");

}

@Override

public void live() {

print(getPersonName() + "住豪宅啊");

}

}

// 调用方式

PoolPersonState poolPersonState = new PoolPersonState(person);

poolPersonState.show();

RichPersonState richPersonState = new RichPersonState(person);

richPersonState.show();

动态的组合状态和对应的人,使其表现出不同的行为,如果有新的状态行为,只要定义新的AbstractState子类即可,在使用的地方就可以组合以下,而不用修改其他的代码,这样提高了代码的维护性和扩展性,满足了开闭原则并且分离了人与状态。 很多模式都很类似,这里的模式网上有很多文章大谈状态模式与策略模式的区别,因为从另一个角度,状态模式的确与策略模式非常类似,把状态State看成策略接口,再把AbstractPersonState看成环境类,就和策略模式如出一辙,的确,甚至把Person定义成抽象类或接口,也能看到桥模式的影子。策略模式解决的是一系列算法中差异算法的封装,可以看成是从另一个角度看待这个模式,而桥模式是从变化维度的角度来管控变化的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值