状态模式

12 阅读3分钟

1. 简介

状态模式(State Pattern)是一种行为设计模式,通常使用它来实现有限状态机(Finite-State Machine),从而解决对象在不同状态下的行为差异问题,并且可以避免使用大量的条件语句来处理这些差异。

2. 模式结构

一个抽象的状态模式的UML关系图如下:

classDiagram
    class Client {
        +main()
    }
    
    class State {
        <<interface>>
        +handle()
    }
    
    class ConcreteState {
        +handle()
    }
    
    class Context {
        -state: State
        +changeState(state: State)
        +handle()
    }
    
    State <|.. ConcreteState
    Context o-- State
    Client ..> Context
    Client ..> ConcreteState
  1. Context(上下文类) :维护一个指向状态对象的引用,这个引用定义了环境对象的当前状态。
  2. State(状态接口) :定义了一个接口,用于封装上下文的特定状态的行为。
  3. ConcreteState(具体状态类) :实现 State 接口,并定义具体状态的行为。
  4. CLient(客户端):调用上下文,并根据不同的条件切换上下文的状态。

3. 优缺点以及使用场景

优点:

  • 封装性:状态相关的操作被封装在具体的状态类中,遵循单一职责原则。
  • 可扩展性:新增状态时,只需增加相应的具体状态类,不会影响到其他类。
  • 减少条件语句:避免在环境类中使用大量的条件语句来判断当前的状态。

缺点:

  • 增加系统复杂性:对于简单的状态逻辑,使用状态模式可能会增加系统的复杂性。
  • 增加对象数量:每个状态都需要一个具体的状态类,可能会增加系统中对象的数量。

应用场景:

  • 对象的行为依赖于其状态,且状态有多种可能。
  • 行为随状态改变而改变,且状态的改变会影响行为的逻辑。

4. 练习:【设计模式专题之状态模式】20-开关台灯

""" 
【设计模式专题之状态模式】20-开关台灯
时间限制:1.000S  空间限制:256MB
题目描述
小明家有一个灯泡,刚开始为关闭状态(OffState)。台灯可以接收一系列的指令,包括打开("ON")、关闭("OFF")和闪烁("blink")。每次接收到一个指令后,台灯会执行相应的操作,并输出当前灯泡的状态。请设计一个程序模拟这个灯泡系统。

输入描述
第一行是一个整数 n(1 <= n <= 1000),表示接收的命令数量。 

接下来的 n 行,每行包含一个字符串 s,表示一个命令("ON"、"OFF"或"blink")。

输出描述
对于每个命令,输出一行,表示执行该命令后灯泡的状态。
输入示例
5
ON
OFF
BLINK
OFF
ON
输出示例
Light is ON
Light is OFF
Light is Blinking
Light is OFF
Light is ON
"""
from abc import ABC, abstractmethod


class State(ABC):
    @abstractmethod
    def show(self):
        raise NotImplemented
        
        
class OnState(State):
    def __init__(self):
        self.name = "ON"
        
    def show(self):
        print(f"Light is ON")
        
        
class OffState(State):
    def __init__(self):
        self.name = "OFF"
        
    def show(self):
        print(f"Light is OFF")
        
        
class BlinkState(State):
    def __init__(self):
        self.name = "BLINK"
        
    def show(self):
        print(f"Light is Blinking")
        
        
class Light:
    def __init__(self, state: State):
        self.state = state
    
    def changeState(self, state: State):
        self.state = state 
        
    def show(self):
        if self.state:
            self.state.show()
        

def client():
    n = int(input())
    light = Light(OffState())
    for _ in range(n):
        stateName = input()
        if stateName == "ON":
            state = OnState()
        elif stateName == "OFF":
            state = OffState()
        else:
            assert stateName == "BLINK"
            state = BlinkState()
        light.changeState(state)
        light.show()
        
        
if __name__ == "__main__":
    client()

5. 参考文章

  1. 有限状态机
  2. refactoringguru-设计模式:状态模式
  3. 卡码网设计模式:状态模式