大话设计模式:第16章 状态模式

第16章:状态模式

状态模式

LongMethod:如果方法过长,极有可能是坏味道代码。方法过长,并且方法中有很多的if判断分支,这就意味若它的责任过大,违反单一职责原则(SRP)。

面向对象设计是希望做到代码的责任分解。

状态(state)模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类.

状态模式主要解决当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

在这里插入图片描述

State类:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。

在这里插入图片描述

ConcreteState类:具体状态,每一个子类实现一个与Context的一个状态相关的行为。

在这里插入图片描述

Context类:维护一个ConcreteState类的实例,这个实例定义当前状态。

在这里插入图片描述

客户端代码

在这里插入图片描述

状态模式好处与用处

状态模式的好处:将与特定状态相关的行为局部化,并且将不同状态的行为分割开。

为了消除庞大的条件分支语句,状态模式将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个Context中,所以通过定义新的子类可以很容易地增加新的状态和转换;状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。

状态模式的使用:当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。

状态模式示例

任务:不同时段的工作状态

在这里插入图片描述

from abc import ABC, abstractmethod
from typing import Text, TypeVar
State = TypeVar("State")
Work = TypeVar("Work")
class Work(object):
    """
    工作类
    """
    def __init__(self) -> None:
        self.__hour = None
        self.__finish = None
        self.__current = ForenoonState()
        
    @property
    def hour(self) -> float:
        return self.__hour
    @hour.setter
    def hour(self, value: float) -> None:
        self.__hour = value
        
    @property
    def task_finished(self) -> bool:
        return self.__finish
    @task_finished.setter
    def task_finished(self, value: bool) -> None:
        self.__finish = value
        
    def set_state(self, s: State) -> None:
        self.__current = s
        
    def write_program(self) -> None:
        self.__current.write_program(self)

class State(ABC):
    """
    抽象状态
    """
    @abstractmethod
    def write_program(self, w: Work) -> None:
        pass
    
class ForenoonState(State):
    """
    上午工作状态
    """
    def write_program(self, w: Work) -> None:
        if w.hour < 12:
            print("当前时间:{}点,上午工作,精神百倍。".format(w.hour))
        else:
            # 超过12点,转入中午工作状态
            w.set_state(NoonState())
            w.write_program()
            
class NoonState(State):
    """
    中午工作状态
    """
    def write_program(self, w: Work) -> None:
        if w.hour < 13:
            print("当前时间:{}点,饿了,午饭;犯困,午休。".format(w.hour))
        else:
            # 超过13点,转入下午工作状态
            w.set_state(AfternoonState())
            w.write_program()
            
class AfternoonState(State):
    """
    下午工作状态
    """
    def write_program(self, w: Work) -> None:
        if w.hour < 17:
            print("当前时间:{}点,下午状态还不错,继续努力。".format(w.hour))
        else:
            # 超过17点,转入晚间工作状态
            w.set_state(EveningState())
            w.write_program()
            
class EveningState(State):
    """
    晚间工作状态
    """
    def write_program(self, w: Work) -> None:
        if w.task_finished:
            # 完成任务,转入下班状态
            w.set_state(RestState())
            w.write_program()
        else:
            if w.hour < 21:
                print("当前时间:{}点,加班哦,疲累至极。".format(w.hour))
            else:
                # 超过21点,转入睡眠工作状态
                w.set_state(SleepingState())
                w.write_program()
            
class SleepingState(State):
    """
    睡眠状态
    """
    def write_program(self, w: Work) -> None:
        print("当前时间:{}点,不行了,睡着了。".format(w.hour))
        
class RestState(State):
    """
    下班休息状态
    """
    def write_program(self, w: Work) -> None:
        print("当前时间:{}点,下班回家了。".format(w.hour))

# 客户端代码
if __name__ == "__main__":
    # 紧急项目
    emergency_projects = Work()
    
    for hour in [9, 10, 12, 13, 14, 17]:
        emergency_projects.hour = hour
        emergency_projects.write_program()
        
    emergency_projects.task_finished = False
    # emergency_projects.task_finished = True
    
    for hour in [19, 22]:
        emergency_projects.hour = hour
        emergency_projects.write_program()
    
    
当前时间:9点,上午工作,精神百倍。
当前时间:10点,上午工作,精神百倍。
当前时间:12点,饿了,午饭;犯困,午休。
当前时间:13点,下午状态还不错,继续努力。
当前时间:14点,下午状态还不错,继续努力。
当前时间:17点,加班哦,疲累至极。
当前时间:19点,加班哦,疲累至极。
当前时间:22点,不行了,睡着了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值