JS规划形式之状况形式:高雅地办理运用中发生的不同状况

一. 前言

在过去,咱们常常运用条件句子(if-else 句子)来处理运用程序中的不同状况。但是,这种方式往往会让代码变得冗长、难以保护,并或许引进潜在的 bug。而状况形式则供给了一种愈加结构化和可扩展的办法来处理状况转化。

简略来说,状况形式将每个状况封装成一个单独的类,并将状况间的转化逻辑封装在一个上下文目标中。经过这种方式,咱们能够依据当时状况的不同,调用不同状况类中的办法来履行相应的逻辑。这种别离状况和行为的做法使得代码愈加灵活和可扩展,并且便于咱们了解和保护。

在本篇文章中,咱们将讨论 JavaScript 状况形式的完结和运用,学习如何运用状况形式来防止 if-else 句子的嵌套,简化杂乱状况的办理,并进步代码的可保护性

那么接下来就让咱们一步步了解如安在现有代码中引进状况形式,并考虑在实践情况中运用状况形式解决常见问题。

二. 什么是状况形式

JavaScript 状况形式是一种行为规划形式,用于经过将目标的行为和状况进行解耦,使得目标能够在不同的状况下具有不同的行为。它答应一个目标在其内部状况改动时更改其行为,而无需改动目标本身的结构。

在状况形式中,目标的行为取决于其当时状况。经过将状况封装为独立的类或目标,状况形式使得状况的改变能够独立于目标本身的改变。运用状况形式,能够将杂乱的、分散的条件句子转化为状况类之间的切换,进步代码的可读性和可保护性。

状况形式一般由以下几个人物组成:

  1. 上下文环境Context):环境是具有状况的目标,它保护一个对当时状况目标的引证,并在状况发生改变时更新本身的行为。

  2. 抽象状况State):抽象状况界说了一个接口,用于封装目标不同状况所对应的行为。

  3. 详细状况Concrete State):详细状况完结了抽象状况界说的接口,并界说了在该状况下目标的详细行为。

JS规划形式之状况形式:高雅地办理运用中发生的不同状况

运用 JavaScript 状况形式能够供给以下优点:

  1. 结构明晰:将状况和行为别离,使代码结构愈加明晰,易于了解和保护。

  2. 可扩展性:添加新的状况类简略,不需要修改其他代码,符合开闭准则

  3. 低耦合:状况形式将状况的切换逻辑放在状况类中,状况之间能够独立改变,下降目标之间的耦合度。

  4. 简化条件判别:状况形式将杂乱的条件句子转化为状况类之间的切换,使代码更简练和可读。

总归,JavaScript 状况形式是一种有用的规划形式,能够协助开发人员办理目标的状况和行为,进步代码的可保护性和可扩展性。

三. 完结方式

在 JavaScript 中,状况形式能够经过以下几个过程来完结:

  1. 界说状况接口State Interface):在 JavaScript 中,咱们能够运用类或目标字面量来界说状况接口。状况接口界说了状况类的一起办法,每个详细状况类都必须完结这些办法。
// 状况接口
class StateInterface {
  handleAction() {
    // 详细状况的行为逻辑
  }
}
// 或许运用目标字面量
const stateInterface = {
  handleAction() {
    // 详细状况的行为逻辑
  },
};
  1. 完结详细状况类Concrete State Class):详细状况类完结状况接口,并界说每个详细状况的行为逻辑。
// 详细状况类
class ConcreteStateA extends StateInterface {
  handleAction() {
    // 详细状况A的行为逻辑
  }
}
class ConcreteStateB extends StateInterface {
  handleAction() {
    // 详细状况B的行为逻辑
  }
}
// 或许运用目标字面量
const concreteStateA = {
  handleAction() {
    // 详细状况A的行为逻辑
  },
};
const concreteStateB = {
  handleAction() {
    // 详细状况B的行为逻辑
  },
};
  1. 界说上下文类Context Class):上下文类包括状况目标,并供给接口供客户端代码调用。上下文类将详细的状况转化逻辑封装在内部,一般会经过改动当时状况来触发不同的行为。
class Context {
  constructor() {
    this.state = null; // 当时状况
  }
  setState(state) {
    this.state = state;
  }
  handleAction() {
    this.state.handleAction();
  }
}
  1. 运用状况形式:在实践运用中,咱们能够经过创建详细的状况目标,并将它们赋值给上下文目标来运用状况形式。
const context = new Context();
// 设置初始状况
context.setState(new ConcreteStateA());
// 调用上下文目标的办法进行详细操作
context.handleAction(); // 依据当时状况,履行对应的行为
// 状况切换
context.setState(new ConcreteStateB());
context.handleAction(); // 依据当时状况,履行对应的行为

经过以上过程,咱们能够完结 JavaScript 中的状况形式。经过封装每个详细状况为单独的类,并在上下文目标中办理状况的切换,咱们能够有用地安排和办理运用程序的不同状况。

这种结构化的规划形式进步了代码的可保护性和可扩展性,一起也添加了代码的可读性和明晰度。

四. 运用场景

举一个最常见的例子,就是电商网站的订单办理,一个订单或许经历多个不同的状况,如待付款待发货运送中已完结等。状况形式能够协助咱们办理和切换这些不同的订单状况,然后处理相应的逻辑。

经过一个简略的代码示例来说明这个场景:

// 界说订单状况接口
class OrderState {
  // 将订单状况作为参数传入,以便在不同状况下履行相应的行为
  constructor(order) {
    this.order = order;
  }
  cancel() {
    throw new Error("该状况下不行撤销订单");
  }
  pay() {
    throw new Error("该状况下不行付出订单");
  }
  ship() {
    throw new Error("该状况下不行发货");
  }
  // 其他或许的订单操作...
}
// 详细订单状况类
class NewOrderState extends OrderState {
  cancel() {
    console.log("订单已撤销");
    this.order.setState(new CancelledOrderState(this.order));
  }
  pay() {
    console.log("订单已付出");
    this.order.setState(new PaidOrderState(this.order));
  }
  ship() {
    console.log("订单未付出,无法发货");
  }
}
class PaidOrderState extends OrderState {
  cancel() {
    console.log("订单已撤销");
    this.order.setState(new CancelledOrderState(this.order));
  }
  pay() {
    console.log("订单已付出,请勿重复付出");
  }
  ship() {
    console.log("订单已发货");
    this.order.setState(new ShippedOrderState(this.order));
  }
}
class ShippedOrderState extends OrderState {
  cancel() {
    console.log("订单已发货,无法撤销");
  }
  pay() {
    console.log("订单已付出,请勿重复付出");
  }
  ship() {
    console.log("订单已发货,请勿重复发货");
  }
  // 其他或许的订单操作...
}
class CancelledOrderState extends OrderState {
  cancel() {
    console.log("订单已撤销,请勿重复撤销");
  }
  // 其他或许的订单操作...
}
// 订单办理类
class Order {
  constructor() {
    // 设置初始状况为新订单状况
    this.state = new NewOrderState(this);
  }
  setState(state) {
    this.state = state;
  }
  cancel() {
    this.state.cancel();
  }
  pay() {
    this.state.pay();
  }
  ship() {
    this.state.ship();
  }
  // 其他或许的订单操作...
}

运用示例如下所示:


const order = new Order();
order.cancel(); // 输出:"该状况下不行撤销订单"
order.pay(); // 输出:"订单已付出"
order.pay(); // 输出:"订单已付出,请勿重复付出"
order.ship(); // 输出:"订单已发货"
order.cancel(); // 输出:"订单已发货,无法撤销"

在上面的代码示例中,咱们首先界说了一个订单状况接口 OrderState,它包括了订单或许的操作办法。

然后,咱们完结了详细的订单状况类 NewOrderStatePaidOrderStateShippedOrderStateCancelledOrderState,每个状况都覆盖了或许的操作,并在状况切换时设置相应的下一个状况。

最后,咱们界说了订单办理类 Order,它包括了订单的当时状况,并供给了一些操作办法用于调用当时状况的相应操作。

经过运用状况形式,咱们能够依据不同的订单状况触发相应的行为,如撤销订单、付出订单、发货等。一起,咱们能够轻松地添加新的状况类,并界说它们所需的行为逻辑,这使得代码结构明晰,并且易于扩展和保护。

五. 总结

JavaScript 状况形式是一种非常有用和强大的规划形式,它能够协助开发人员办理目标的不同状况和相应的行为。经过将状况和行为别离,状况形式能够进步代码的可扩展性和复用性。

一般来说,状况形式具有许多优点,它能够使代码结构愈加明晰易于了解和保护。经过将分散的、冗长的条件句子转化为状况类之间的切换,代码变得愈加简练和可读。此外,状况形式支持体系的扩展性,遵从开闭准则,方便添加新的状况类和行为。

但是,状况形式也有一些缺点。引进状况形式后,或许会添加类和目标的数量,然后添加代码的杂乱度了解难度。在状况转化较为简略的场景中,引进状况形式或许并不切实践,会添加体系杂乱性。

在实践运用中,要权衡状况形式的优缺点,依据详细的场景和需求进行选择。当目标有多个状况且状况之间存在杂乱的转化逻辑时,状况形式是一个非常好的选择。