状态模式

状态模式:允许一个对象在其内部状态发生改变时改变其行为,使这个对象看上去就像改变了它的类型一样。
生活中的设计模式:比如你最近你是一个减肥中的吃货,你决定每天开始跑。,但是你跑了步后总是嘴馋,所以你跟你自己默默的做了一个约定。跑小于2公里以下时,不能吃任何东西;跑2~3公里,跑完能吃一根香蕉;跑3~4公里,跑玩能吃一个苹果;跑了4~5公里,能吃一个红薯;跑大于5公里时,能吃一个汉堡。
此案例,跑步的里程可以当作对象内部的状态改变,随着跑步里程的不同,所能吃的食物也不一样;代码如下:

from abc import ABCMeta, abstractmethod


class Running(metaclass=ABCMeta):
    """跑步里程抽象类"""
    def __init__(self):
        self.__state = []
        self.__current_state = None
        self.__miles = 0

    def add_state(self, state):
        if state not in self.__state:
            self.__state.append(state)

    def change_state(self, state):
        if state is None:
            return False
        if self.__current_state is None:
            print("Init: ", state.get_name())
        else:
            print("State has changed: {0} --> {1}".format(self.get_state().get_name(), state.get_name()))
        self.__current_state = state
        self.add_state(state)

    def get_state(self):
        return self.__current_state

    def _set_running_miles(self, miles):
        self.__miles = miles
        print("Running miles: ", self.__miles)
        for state in self.__state:
            if state.is_match(self.__miles):
                self.change_state(state)

    def _get_running_miles(self):
        return self.__miles



class Miles(Running):
    """跑步里程类"""
    def __init__(self):
        super().__init__()
        self.add_state(EatAir("空气"))
        self.add_state(EatBanana("香蕉"))
        self.add_state(EatApple("苹果"))
        self.add_state(EatSweetPotato("红薯"))
        self.add_state(EatHamburger("汉堡"))
        self.set_miles(0)

    def increase_miles(self, miles):
        self.set_miles(self._get_running_miles() + miles)

    def decrease_miles(self, miles):
        self.set_miles(self._get_running_miles() - miles)

    def set_miles(self, miles):
        return self._set_running_miles(miles)

    def eat(self):
        self.get_state().eat()


class Eat:
    """吃东西类"""
    def __init__(self, name):
        self.__name = name

    @abstractmethod
    def eat(self):
        pass

    def get_name(self):
        return self.__name


class EatAir(Eat):
    """吃空气"""
    def __init__(self, name):
        super().__init__(name)

    def eat(self):
        print("Eat Air.")

    def is_match(self, mile):
        return mile <= 2


class EatBanana(Eat):
    """吃香蕉"""
    def __init__(self, name):
        super().__init__(name)

    def eat(self):
        print("Eat Banana.")

    def is_match(self, mile):
        return 2 < mile <= 3


class EatApple(Eat):
    """吃苹果"""
    def __init__(self, name):
        super().__init__(name)

    def eat(self):
        print("Eat Apple.")

    def is_match(self, mile):
        return 3 < mile <= 4


class EatSweetPotato(Eat):
    """吃红薯"""
    def __init__(self, name):
        super().__init__(name)

    def eat(self):
        print("Eat SweetPotato.")

    def is_match(self, mile):
        return 4 < mile <= 5


class EatHamburger(Eat):
    """吃汉堡"""
    def __init__(self, name):
        super().__init__(name)

    def eat(self):
        print("Eat Hamburger.")

    def is_match(self, mile):
        return 5 < mile


def test():
    """测试方法"""
    runing_miles = Miles()
    runing_miles.eat()
    runing_miles.increase_miles(5)
    runing_miles.eat()
    runing_miles.decrease_miles(1)
    runing_miles.eat()
    runing_miles.increase_miles(2)
    runing_miles.eat()
    runing_miles.decrease_miles(3)
    runing_miles.eat()

test()

其实单纯从上述案例的需求来说,IF -- ELSE 可能是更好的选择;因为上述案例的对象的属性状态简单,并不复杂,判断起来比较简单;但是当对象属性状态复杂的情形下,状态模式就能排上用场了。

状态模式的应用场景:(1)一个对象的行为取决于它的状态,并且它在运行时可能经常改变它的状态,从而改变它的行为。
(2)一个操作中含有庞大的多分支条件语句,这些分支以来于该对象的状态,且每一个分支的业务逻辑都非常复杂时,我们可以使用状态模式来拆分不同的分支逻辑,使程序有更好的可读性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值