第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点,不行了,睡着了。