灌篮少年 发表于 2024-9-10 12:15:09

漫谈计划模式 [17]:状态模式

引导性开场

菜鸟:老鸟,我近来在写一个项目,遇到一个题目。我们有一个订单系统,不同的订单状态必要执行不同的操纵。如今代码里布满了各种 if-else 语句,维护起来好痛苦。有没有什么好的解决办法?
老鸟:你这个题目很常见,很多人都会遇到类似的痛点。你有没有听说过状态模式?
菜鸟:状态模式?似乎听过,但不太相识。
老鸟:没关系,我们可以一步步来。先讲讲你如今的实现方式吧。
渐进式先容概念

菜鸟:好的,我如今是这样写的:
class Order:
    def __init__(self):
      self.state = "pending"
   
    def process(self):
      if self.state == "pending":
            print("Processing pending order")
            self.state = "shipped"
      elif self.state == "shipped":
            print("Order has already been shipped")
      elif self.state == "delivered":
            print("Order has already been delivered")

order = Order()
order.process()
order.process()
老鸟:我明确了。这种方式确实可以工作,但随着状态和操纵的增多,代码会变得越来越复杂。我们可以用状态模式来改进这个题目。状态模式的核心头脑是:将状态和行为封装在独立的状态类中,通过改变状态对象来改变对象的行为。
菜鸟:听起来有点抽象,能不能用一个简单的例子表明一下?
老鸟:当然可以。你可以把订单的状态比作交通灯,不同的灯光对应不同的行为。比如,红灯停,绿灯行,黄灯警告。每种灯光都是一种状态,不同状态下有不同的行为。
Python代码示例,逐步展开

菜鸟:明确了,那我们怎么用Python实现这个状态模式呢?
老鸟:我们可以把每种状态抽象成一个类,定义它们各自的行为。然后在订单类中维护一个当前状态对象,通过调用状态对象的方法来执行相应的操纵。
第一步:定义状态接口和详细状态类

from abc import ABC, abstractmethod

class OrderState(ABC):
    @abstractmethod
    def process(self, order):
      pass

class PendingState(OrderState):
    def process(self, order):
      print("Processing pending order")
      order.state = ShippedState()

class ShippedState(OrderState):
    def process(self, order):
      print("Order has already been shipped")

class DeliveredState(OrderState):
    def process(self, order):
      print("Order has already been delivered")
菜鸟:这些类看起来很清楚,每个状态类都实现了 OrderState 接口,并定义了本身的 process 方法。
第二步:在订单类中利用状态对象

class Order:
    def __init__(self):
      self.state = PendingState()
   
    def process(self):
      self.state.process(self)
菜鸟:我明确了,我们把状态的逻辑从订单类中分离出来,每个状态类只负责本身的逻辑。订单类只必要维护一个当前状态对象,并调用它的 process 方法。
题目与反思

菜鸟:这种方式确实比 if-else 更清楚,但如果我直接修改状态对象,比如 order.state = DeliveredState(),会不会有题目?
老鸟:确实,这样会破坏状态模式的封装性。我们应该通过状态对象的方法来改变状态,而不是直接修改状态对象。你可以在状态类中添加一个方法来改变状态,比如 set_state 方法。
优化后的实现

class Order:
    def __init__(self):
      self.state = PendingState()
   
    def set_state(self, state):
      self.state = state
   
    def process(self):
      self.state.process(self)
更新状态类中的行为

class PendingState(OrderState):
    def process(self, order):
      print("Processing pending order")
      order.set_state(ShippedState())

class ShippedState(OrderState):
    def process(self, order):
      print("Order has already been shipped")

class DeliveredState(OrderState):
    def process(self, order):
      print("Order has already been delivered")
优势与实用场景

老鸟:状态模式的优势在于,它将状态逻辑分散到单独的状态类中,使得代码更加清楚和易于维护。它的实用场景包罗:


[*]对象的行为依赖于其状态,并且必要在运行时根据状态改变行为。
[*]必要克制大量的条件语句来处置惩罚状态转换。
菜鸟:嗯,听起来挺有原理的。
常见误区与优化发起

老鸟:必要留意的是,状态模式也有一些常见的误区,比如:


[*]过度计划:不须要的情况下利用状态模式会增长代码复杂性。
[*]状态转换逻辑分散:状态转换逻辑分散在各个状态类中,可能会导致难以追踪。
优化发起是:在利用状态模式时,要确保确实必要这种模式,并且在计划时尽量保持状态转换逻辑的一致性和可追踪性。
总结与延伸阅读

老鸟:本日我们通过一个订单系统的例子,逐步讲解了状态模式的概念和实现。状态模式可以让你的代码更加清楚和易于维护,但在利用时也要留意克制过度计划。你可以进一步阅读《计划模式:可复用面向对象软件的基础》这本书,它详细先容了各种计划模式,包罗状态模式。
菜鸟:谢谢老鸟,本日学到了很多。我计划继续学习其他计划模式,有什么推荐的吗?
老鸟:你可以接着学习计谋模式和观察者模式,它们也是非常实用的计划模式。加油!
菜鸟:好的,我会继续学习的!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 漫谈计划模式 [17]:状态模式