跳至主要內容

状态模式

约 532 字

状态模式

核心思想

状态模式允许一个对象在其内部状态改变时改变它的行为,使其看上去就像改变了自身所属的类。

典型用例

订单管理

在订单管理系统中,订单会有不同的状态: 新订单、已支付、已发货、已完成、已取消。每个状态会有不同的处理逻辑。

在这个例子中,每个具体的订单状态类都知道如何处理当前状态并将上下文移至下一状态,这种方式使得添加新的状态或改变状态转换逻辑变得非常容易,因为每个状态的逻辑都封装在自己的类中。

// npm run code src/code/design-pattern/state/order.ts

export {};

// 为所有具体状态定义一个共同的接口
interface OrderState {
    handleOrder(orderContext: OrderContext): void;
}

// 为每个可能的订单状态定义一个具体状态类,每个类都实现抽象的状态接口
class NewOrderState implements OrderState {
    handleOrder(orderContext: OrderContext): void {
        console.log("Handling new order");
        orderContext.setState(new PaidOrderState());
    }
}

class PaidOrderState implements OrderState {
    handleOrder(orderContext: OrderContext): void {
        console.log("Handling paid order");
        orderContext.setState(new ShippedOrderState());
    }
}

class ShippedOrderState implements OrderState {
    handleOrder(orderContext: OrderContext): void {
        console.log("Handling shipped order");
        orderContext.setState(new CompletedOrderState());
    }
}

class CompletedOrderState implements OrderState {
    handleOrder(orderContext: OrderContext): void {
        console.log("Order is completed");
    }
}

class CancelledOrderState implements OrderState {
    handleOrder(orderContext: OrderContext): void {
        console.log("Order has been cancelled");
    }
}

// 创建一个上下文类,它将维护当前状态,并允许状态切换
class OrderContext {
    private state: OrderState;

    constructor(state: OrderState) {
        this.state = state;
    }

    setState(state: OrderState): void {
        this.state = state;
    }

    handleOrder(): void {
        this.state.handleOrder(this);
    }
}

const order = new OrderContext(new NewOrderState());
order.handleOrder(); // 处理新建订单
order.handleOrder(); // 处理已支付订单
order.handleOrder(); // 处理已发货订单

状态机管理

当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,可以使用状态模式。例如,在游戏开发中管理游戏角色的状态(如运行、跳跃、攻击)。

// npm run code src/code/design-pattern/state/state-machine-management.ts

export {};

// 状态接口
interface State {
    handle(context: CharacterContext): void;
}

// 角色上下文
class CharacterContext {
    private state: State;

    constructor(state: State) {
        this.state = state;
    }

    setState(state: State): void {
        this.state = state;
    }

    request(): void {
        this.state.handle(this);
    }
}

// 具体状态:运行
class RunningState implements State {
    handle(context: CharacterContext): void {
        console.log('角色正在跑步');
        // 可以根据需要切换到其他状态
        // context.setState(new AnotherState());
    }
}

// 具体状态:跳跃
class JumpingState implements State {
    handle(context: CharacterContext): void {
        console.log('角色正在跳跃');
    }
}

// 具体状态:攻击
class AttackingState implements State {
    handle(context: CharacterContext): void {
        console.log('角色正在攻击');
    }
}

const character = new CharacterContext(new RunningState());
character.request(); // 输出: 角色正在跑步

character.setState(new JumpingState());
character.request(); // 输出: 角色正在跳跃

character.setState(new AttackingState());
character.request(); // 输出: 角色正在攻击

界面控件的状态

在用户界面设计中,可以使用状态模式来管理控件的不同状态。每个状态(如普通、悬浮、按下、禁用)都可以有自己的行为和外观。

// npm run code src/code/design-pattern/state/interface-control-state.ts

export {};

// 状态接口
interface ButtonState {
    click(buttonContext: ButtonContext): void;
    hover(buttonContext: ButtonContext): void;
    leave(buttonContext: ButtonContext): void;
}

// 按钮上下文
class ButtonContext {
    private state: ButtonState;

    constructor(state: ButtonState) {
        this.state = state;
    }

    setState(state: ButtonState): void {
        this.state = state;
        console.log(`按钮状态变为:${state.constructor.name}`);
    }

    click(): void {
        this.state.click(this);
    }

    hover(): void {
        this.state.hover(this);
    }

    leave(): void {
        this.state.leave(this);
    }
}

// 具体状态:普通
class NormalState implements ButtonState {
    click(buttonContext: ButtonContext): void {
        console.log('按钮被点击');
        // 可以根据需要切换到其他状态
    }

    hover(buttonContext: ButtonContext): void {
        buttonContext.setState(new HoverState());
    }

    leave(buttonContext: ButtonContext): void {
        // 通常情况下,普通状态下离开不会有特殊行为
    }
}

// 具体状态:悬浮
class HoverState implements ButtonState {
    click(buttonContext: ButtonContext): void {
        console.log('按钮被点击(悬浮状态)');
        // 可以根据需要切换到其他状态
    }

    hover(buttonContext: ButtonContext): void {
        // 悬浮状态下继续悬浮通常不会有特殊行为
    }

    leave(buttonContext: ButtonContext): void {
        buttonContext.setState(new NormalState());
    }
}


const button = new ButtonContext(new NormalState());

button.hover(); // 输出: 按钮状态变为:HoverState
button.click(); // 输出: 按钮被点击(悬浮状态)
button.leave(); // 输出: 按钮状态变为:NormalState

网络连接管理

状态模式适合用于管理网络连接的不同状态,如连接、断开、正在连接、连接失败等。每个状态可以有其特定的行为,比如尝试重新连接或显示错误信息。

// npm run code src/code/design-pattern/state/network-connection-management.ts

export {};

// 状态接口
interface ConnectionState {
    connect(connectionContext: ConnectionContext): void;
    disconnect(connectionContext: ConnectionContext): void;
    fail(connectionContext: ConnectionContext): void;
}

// 连接上下文
class ConnectionContext {
    private state: ConnectionState;

    constructor(state: ConnectionState) {
        this.state = state;
    }

    setState(state: ConnectionState): void {
        this.state = state;
        console.log(`连接状态变为:${state.constructor.name}`);
    }

    connect(): void {
        this.state.connect(this);
    }

    disconnect(): void {
        this.state.disconnect(this);
    }

    fail(): void {
        this.state.fail(this);
    }
}

// 具体状态:连接
class ConnectedState implements ConnectionState {
    connect(connectionContext: ConnectionContext): void {
        console.log('已经连接,无需再次连接');
    }

    disconnect(connectionContext: ConnectionContext): void {
        console.log('断开连接');
        connectionContext.setState(new DisconnectedState());
    }

    fail(connectionContext: ConnectionContext): void {
        console.log('连接时发生错误');
        connectionContext.setState(new FailedState());
    }
}

// 具体状态:断开
class DisconnectedState implements ConnectionState {
    connect(connectionContext: ConnectionContext): void {
        console.log('正在连接...');
        connectionContext.setState(new ConnectingState());
    }

    disconnect(connectionContext: ConnectionContext): void {
        console.log('已经断开,无需再次断开');
    }

    fail(connectionContext: ConnectionContext): void {
        console.log('连接失败');
        connectionContext.setState(new FailedState());
    }
}

// 具体状态:正在连接
class ConnectingState implements ConnectionState {
    connect(connectionContext: ConnectionContext): void {
        console.log('已经在连接中...');
    }

    disconnect(connectionContext: ConnectionContext): void {
        console.log('连接尚未完成,无法断开');
    }

    fail(connectionContext: ConnectionContext): void {
        console.log('连接失败');
        connectionContext.setState(new FailedState());
    }
}

// 具体状态:连接失败
class FailedState implements ConnectionState {
    connect(connectionContext: ConnectionContext): void {
        console.log('尝试重新连接...');
        connectionContext.setState(new ConnectingState());
    }

    disconnect(connectionContext: ConnectionContext): void {
        console.log('已经断开');
        connectionContext.setState(new DisconnectedState());
    }

    fail(connectionContext: ConnectionContext): void {
        console.log('连接失败');
    }
}

const connection = new ConnectionContext(new DisconnectedState());

connection.connect(); // 输出: 正在连接...
// 假设连接成功
connection.setState(new ConnectedState());

connection.disconnect(); // 输出: 断开连接

工作流管理

在工作流或流程控制系统中,状态模式适合于管理不同的工作流状态(如审批、审核、拒绝、完成)。状态模式可以帮助清晰地定义在每个状态下应该执行的操作,以及如何从一个状态转换到另一个状态。

// npm run code src/code/design-pattern/state/workflow-management.ts

export {};

// 工作流状态接口
interface WorkflowState {
    approve(workflowContext: WorkflowContext): void;
    reject(workflowContext: WorkflowContext): void;
    audit(workflowContext: WorkflowContext): void;
    complete(workflowContext: WorkflowContext): void;
}

// 工作流上下文
class WorkflowContext {
    private state: WorkflowState;

    constructor(state: WorkflowState) {
        this.state = state;
        console.log(`初始化工作流,状态为:${state.constructor.name}`);
    }

    setState(state: WorkflowState): void {
        this.state = state;
        console.log(`工作流状态变为:${state.constructor.name}`);
    }

    approve(): void {
        this.state.approve(this);
    }

    reject(): void {
        this.state.reject(this);
    }

    audit(): void {
        this.state.audit(this);
    }

    complete(): void {
        this.state.complete(this);
    }
}

// 具体状态:审批
class ApprovalState implements WorkflowState {
    approve(workflowContext: WorkflowContext): void {
        console.log('审批通过');
        workflowContext.setState(new AuditState());
    }

    reject(workflowContext: WorkflowContext): void {
        console.log('审批被拒绝');
        workflowContext.setState(new RejectedState());
    }

    audit(workflowContext: WorkflowContext): void {
        console.log('当前状态不支持审核操作');
    }

    complete(workflowContext: WorkflowContext): void {
        console.log('当前状态不支持完成操作');
    }
}

// 具体状态:审核
class AuditState implements WorkflowState {
    approve(workflowContext: WorkflowContext): void {
        console.log('已通过审核');
        workflowContext.setState(new CompletedState());
    }

    reject(workflowContext: WorkflowContext): void {
        console.log('审核被拒绝');
        workflowContext.setState(new RejectedState());
    }

    audit(workflowContext: WorkflowContext): void {
        console.log('正在进行审核');
    }

    complete(workflowContext: WorkflowContext): void {
        console.log('当前状态不支持完成操作');
    }
}

// 具体状态:拒绝
class RejectedState implements WorkflowState {
    approve(workflowContext: WorkflowContext): void {
        console.log('拒绝状态下不能进行审批');
    }

    reject(workflowContext: WorkflowContext): void {
        console.log('已经是拒绝状态');
    }

    audit(workflowContext: WorkflowContext): void {
        console.log('拒绝状态下不能进行审核');
    }

    complete(workflowContext: WorkflowContext): void {
        console.log('拒绝状态下不能标记为完成');
    }
}

// 具体状态:完成
class CompletedState implements WorkflowState {
    approve(workflowContext: WorkflowContext): void {
        console.log('完成状态下不能进行审批');
    }

    reject(workflowContext: WorkflowContext): void {
        console.log('完成状态下不能被拒绝');
    }

    audit(workflowContext: WorkflowContext): void {
        console.log('完成状态下不能进行审核');
    }

    complete(workflowContext: WorkflowContext): void {
        console.log('已经是完成状态');
    }
}

// 示例使用
const workflow = new WorkflowContext(new ApprovalState());
workflow.approve(); // 审批通过,进入审核状态
workflow.approve(); // 通过审核,进入完成状态
workflow.complete(); // 已经是完成状态

上次编辑于: