DesignPattern - 状态模式【行为型】

1,085 阅读3分钟

欢迎关注微信公众号:FSA全栈行动 👋

一、状态模式介绍

状态模式(State Pattern)属于行为型模式。对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为,允许一个对象在其内部状态改变时改变它的行为。

注意:状态模式与策略模式是孪生兄弟,它们的 UML 图是一样的,但实际上解决的是不同情况的两种场景问题,状态模式不同状态下做的事情不同,而策略模式做的都是同一件事。

  • 核心组成

    • Context 上下文:定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的 ConcreteState 对象来处理
    • State 抽象状态类:定义一个接口以封装与 Context 的一个特定状态相关的行为
    • ConcreteState 具体状态类:实现抽象状态定义的接口
  • 应用场景

    • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
    • 代码中包含大量与对象状态有关的条件语句,比如一个操作中含有庞大的多分支的条件 if-else 语句,且这些分支依赖于该对象的状态
    • 电商订单状态:未支付、已支付、派送中,收货完成等状态,各个状态下处理不同的事情
  • 优点

    • 只需要改变对象状态即可改变对象的行为
    • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
  • 缺点

    • 状态模式的使用会增加系统类和对象的个数
    • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
    • 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码

二、状态模式代码实现

以 电商订单状态变更,调用各种服务 为例

创建抽象状态:

/**
 * 抽象状态
 *
 * @author GitLqr
 */
public interface State {

	// 处理状态相关的行为
	void handle();
}

定义具体状态:

/**
 * 具体状态类:新订单
 *
 * @author GitLqr
 */
public class NewOrderState implements State {
	@Override
	public void handle() {
		System.out.println("新订单,未支付");
		System.out.println("调用商户客服服务,有新订单\n");
	}
}
/**
 * 具体状态类:订单已支付
 *
 * @author GitLqr
 */
public class PayOrderState implements State {
	@Override
	public void handle() {
		System.out.println("订单已经支付");
		System.out.println("调用商户客服服务,订单已经支付");
		System.out.println("调用物流服务,未发货\n");
	}
}
/**
 * 具体状态类:订单已发货
 *
 * @author GitLqr
 */
public class SendOrderState implements State {
	@Override
	public void handle() {
		System.out.println("订单已经发货");
		System.out.println("调用短信服务,通知用户已经发货");
		System.out.println("更新物流信息\n");
	}
}

创建上下文:

/**
 * 上下文:订单状态更新 就执行 状态对应的行为
 *
 * @author GitLqr
 */
public class OrderContext {
	private State state;

	public void setState(State state) {
		this.state = state;
		System.out.println("订单状态变更!!");
		this.state.handle();
	}
}

使用:

public static void main(String[] args) {
    OrderContext orderContext = new OrderContext();
    orderContext.setState(new NewOrderState());
    orderContext.setState(new PayOrderState());
    orderContext.setState(new SendOrderState());
}

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~