模式简介
允许一个对象在其内部状态改变时改变它的行为. 对象看起来似乎修改了它的类.
在某些情况下, 一个对象的行为取决于它当前所处的状态, 当对象属性 (状态) 在系统运行过程中发生变化, 它呈现出的行为也随之发生改变. 例如可调节亮度的台灯, 假设灯光亮度分为三级, 每次按下按钮, 台灯会根据当前亮度增加一级, 若已经是最亮的状态, 按下按钮则关闭台灯.
结构分析
UML 类图
角色说明
Context
环境类. 客户端操作的类, 包含一个 IState 类型的对象, 保存其当前状态.
IState
状态接口. 定义一个统一的接口以封装与 Context 的特定状态相关的行为.
ConcreteState
具体状态. 实现状态接口, 表示 Context 某个状态相关的行为.
工作原理
Context 类将与状态相关的请求委托给 ConcreteState 对象处理, 并将自身以参数形式传递给 ConcreteState 对象, 如此, 便可以在处理完请求后访问 Context 的 SetState 方法为 Context 设置新的状态.
结构代码
- // 环境类
- class Context
- {
- private IState _state;
- public Context(IState state)
- {
- _state = state;
- Console.WriteLine($"Initialize state -> {state}");
- }
- public void SetState(IState state)
- {
- _state = state;
- Console.WriteLine($"Set State -> {state}");
- }
- public void Request()
- {
- _state.Handle(this);
- }
- }
- // 状态接口
- interface IState
- {
- void Handle(Context context);
- }
- // 具体状态类 A
- class ConcreteStateA : IState
- {
- public void Handle(Context context)
- {
- context.SetState(new ConcreteStateB());
- }
- }
- // 具体状态类 B
- class ConcreteStateB : IState
- {
- public void Handle(Context context)
- {
- context.SetState(new ConcreteStateA());
- }
- }
- // 客户端调用
- static void Main(string[] args)
- {
- Context context = new Context(new ConcreteStateA());
- for (int i = 0; i <5; i++)
- {
- context.Request();
- }
- Console.ReadLine();
- }
程序输出:
示例分析
本节模拟第一节中提到的台灯示例. 首先创建台灯类 Lamp, 提供共有方法 SetState 设置当前状态, 包含一个保存当前状态的私有字段_state, 并通过 Request 方法调用该状态的下台灯发光的行为.
- class Lamp
- {
- private IState _state;
- public Lamp(IState state)
- {
- _state = state;
- Console.WriteLine($"Initialize state -> {state}");
- }
- public void SetState(IState state)
- {
- _state = state;
- Console.WriteLine($"Set State -> {state}");
- }
- public void Request()
- {
- _state.Handle(this);
- }
- }
声明状态接口, 并分别实现具体状态类, 这里包括四种状态 Closed,Dim,Medium,Bright.
- interface IState
- {
- void Handle(Lamp context);
- }
- class Closed : IState
- {
- public void Handle(Lamp context)
- {
- context.SetState(new Dim());
- }
- }
- class Dim : IState
- {
- public void Handle(Lamp context)
- {
- context.SetState(new Medium());
- }
- }
- class Medium : IState
- {
- public void Handle(Lamp context)
- {
- context.SetState(new Bright());
- }
- }
- class Bright : IState
- {
- public void Handle(Lamp context)
- {
- context.SetState(new Closed());
- }
- }
客户端调用, 将台灯的初始状态设置为 Closed, 并连续调用, 输出台灯状态.
- class Program
- {
- static void Main(string[] args)
- {
- Lamp lamp = new Lamp(new Closed());
- for (int i = 0; i < 10; i++)
- {
- lamp.Request();
- }
- Console.ReadLine();
- }
- }
程序输出:
适用场景
一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为.
一个操作中含有大量的分支的条件语句, 且这些分支依赖于该对象的状态.
来源: https://www.cnblogs.com/Answer-Geng/p/9319827.html