同样是水,固态,气态,液态的变化,是由温度引起。

引此为思考状态模式。

from abc import ABCMeta, abstractmethod
# 引入ABCMeta和abstractmethod来定义抽象类和抽象方法

"""
version 1.0
class Water:

    def __init__(self, state):
        self.__temperature = 25
        self.__state = state

    def set_state(self, state):
        self.__state = state

    def change_state(self, state):
        if self.__state:
            print("由 {} 变为 {}".format(self.__state.get_name(), state.get_name()))

        else:
            print("初始化为{}".format(state.get_name()))
        self.__state = state

    def get_temperature(self):
        return self.__temperature

    def set_temperature(self, temperature):
        self.__temperature = temperature
        if self.__temperature <= 0:
            self.change_state(SolidState("固态"))
        elif self.__temperature <= 100:
            self.change_state(LiquidState("液态"))
        else:
            self.change_state(GaseousState("气态"))

    def rise_temperature(self, step):
        self.set_temperature(self.__temperature + step)

    def reduce_temperature(self, step):
        self.set_temperature(self.__temperature - step)

    def behavior(self):
        self.__state.behavior(self)

class State:

    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    @abstractmethod
    def behavior(self, water):
        pass

class SolidState(State):
    def __init__(self, name):
        super().__init__(name)

    def behavior(self, water):
        print("当前体温: {}".format(str(water.get_temperature())))

class LiquidState(State):
    def __init__(self, name):
        super().__init__(name)

    def behavior(self, water):
        print("当前体温: {}".format(str(water.get_temperature())))

class GaseousState(State):
    def __init__(self, name):
        super().__init__(name)

    def behavior(self, water):
        print("当前体温: {}".format(str(water.get_temperature())))

def test_state():
    water = Water(LiquidState("液态"))
    water.behavior()
    water.set_temperature(-4)
    water.behavior()
    water.rise_temperature(18)
    water.behavior()
    water.rise_temperature(110)
    water.behavior()

test_state()
"""

# version 2.0
class Context(metaclass=ABCMeta):

    def __init__(self):
        self.__states = []
        self.__cur_state = None
        self.__state_info = 0

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

    def change_state(self, state):
        if state is None:
            return False
        if self.__cur_state is None:
            print("初始化为: {}".format(state.get_name()))
        else:
            print("由 {} 变为 {}".format(self.__cur_state.get_name(), state.get_name()))
        self.__cur_state = state
        self.add_state(state)
        return True

    def get_state(self):
        return self.__cur_state

    def _set_state_info(self, state_info):
        self.__state_info = state_info
        for state in self.__states:
            if state.is_match(state_info):
                self.change_state(state)

    def _get_state_info(self):
        return self.__state_info

class State:
    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    def is_match(self, state_info):
        return False

    @abstractmethod
    def behavior(self, context):
        pass

class Water(Context):

    def __init__(self):
        super().__init__()
        self.add_state(SolidState("固态"))
        self.add_state(LiquidState("液态"))
        self.add_state(GaseousState("气态"))
        self.set_temperature(25)

    def get_temperature(self):
        return self._get_state_info()

    def set_temperature(self, temperature):
        self._set_state_info(temperature)

    def rise_temperature(self, step):
        self.set_temperature(self.get_temperature() + step)

    def reduce_temperature(self, step):
        self.set_temperature(self.get_temperature() - step)

    def behavior(self):
        state = self.get_state()
        if isinstance(state, State):
            state.behavior(self)

def singleton(cls, *args, **kwargs):
    instance = {}

    def __singletone(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]

    return __singletone

@singleton
class SolidState(State):
    def __init__(self, name):
        super().__init__(name)

    def is_match(self, state_info):
        return state_info < 0

    def behavior(self, context):
        print(", 我性格高冷, 当前体温: {}".format(context._get_state_info()))

@singleton
class LiquidState(State):
    def __init__(self, name):
        super().__init__(name)

    def is_match(self, state_info):
        return 0 <= state_info < 100

    def behavior(self, context):
        print("我性格温和, 当前体温: {}".format(context._get_state_info()))

@singleton
class GaseousState(State):
    def __init__(self, name):
        super().__init__(name)

    def is_match(self, state_info):
        return state_info >= 100

    def behavior(self, context):
        print("我性格热烈,当前体温: {}".format(context._get_state_info()))

def test_state():
    water = Water()
    water.behavior()
    water.set_temperature(-4)
    water.behavior()
    water.rise_temperature(18)
    water.behavior()
    water.rise_temperature(110)
    water.behavior()

test_state()
C:\Python36\python.exe C:/Users/Sahara/PycharmProjects/test/python_search.py
初始化为: 液态
我性格温和, 当前体温:
由 液态 变为 固态
, 我性格高冷, 当前体温: -
由 固态 变为 液态
我性格温和, 当前体温:
由 液态 变为 气态
我性格热烈,当前体温: 

Process finished with exit code 

<人人都懂设计模式>-状态模式的更多相关文章

  1. <人人都懂设计模式>-中介模式

    真正的用房屋中介来作例子, 好的书籍总是让人记忆深刻. class HouseInfo: def __init__(self, area, price, has_window, has_bathroo ...

  2. <人人都懂设计模式>-单例模式

    这个模式,我还是了解的. 书上用了三种不同的方法. class Singleton1: # 单例实现方式1 __instance = None __is_first_init = False def ...

  3. <人人都懂设计模式>-装饰模式

    书上,真的用一个人穿衣打拌来讲解装饰模式的呢. from abc import ABCMeta, abstractmethod class Person(metaclass=ABCMeta): def ...

  4. 14. 星际争霸之php设计模式--状态模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  5. 人人都懂区块链--pdf电子版学习资料下载

    人人都懂区块链 21天从区块链“小白”到资深玩家电子版pdf下载 链接:https://pan.baidu.com/s/1TWxYv4TLa2UtTgU-HqLECQ 提取码:6gy0 好的学习资料需 ...

  6. [Head First设计模式]生活中学设计模式——状态模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. 深入浅出设计模式——状态模式(State Pattern)

    模式动机 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的 (stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的.当一个这样的 ...

  8. 24种设计模式--状态模式【State Pattern】

    现在城市发展很快,百万级人口的城市一堆一堆的,那其中有两个东西的发明在城市的发展中起到非常重要的作用:一个是汽车,一个呢是...,猜猜看,是什么?是电梯!汽车让城市可以横向扩展,电梯让城市可以纵向延伸 ...

  9. C++设计模式——状态模式

    前言 在实际开发中,我们经常会遇到这种情况:一个对象有多种状态,在每一个状态下,都会有不同的行为.那么在代码中我们经常是这样实现的. typedef enum tagState { state, st ...

随机推荐

  1. 【ECNU3386】Hunter's Apprentice(多边形有向面积)

    点此看题面 大致题意: 按顺序给你一个多边形的全部顶点,让你判断是按顺时针还是逆时针给出的. 多边形有向面积 显然我们知道,叉积可以求出两个向量之间有向面积的两倍. 所以,我们三角剖分,就可以求出四边 ...

  2. Linux性能优化实战学习笔记:第四十七讲

    一.上节回顾 上一节,我们梳理了,应用程序容器化后性能下降的分析方法.一起先简单回顾下.容器利用 Linux 内核提供的命名空间技术,将不同应用程序的运行隔离起来,并用统一的镜像,来管理应用程序的依赖 ...

  3. vue中子组件的methods中获取到props中的值

    这个官网很清楚,也很简单,父组件中使用v-bind绑定传送,子组件使用props接收即可 例如: 父组件中 <template> <div> <head-top>& ...

  4. [解決方案]IIS配置后报错500.21

    如果报错这个信息,那么就是aspnet未注册造成的,需要安装一下 步骤: 1.打开CMD 2.输入cd %windir%\Microsoft.Net\Framework\v4.0.30319 3.执行 ...

  5. Spring Boot Cache使用与整合

    Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Caffeine.Ehcache等),但本身不直接提供缓存功能的实现.它支持注解方式使用缓存,非常方便. SpringBoot在a ...

  6. Spring事务调用类自己方法失效解决办法和原因

    问题 正常情况下,我们都是在controller里调用service里的方法,这个方法如果需要加事务,就在方法上加上@Transactional,这样是没问题的,事务会生效. 可是如果像下面这样,绕以 ...

  7. Vue2 实践揭秘 错误列表

    京东上的购买地址 作者是土生土长的聪明中国人 https://item.jd.com/12176536.html 64页 const bookID = this.$router.params.id 搞 ...

  8. javascript碰撞检测的方法

    javascript碰撞检测的方法需要把要检测碰撞的精灵都放到数组里array push 然后循环遍历数组里的精灵检测碰撞 ps:不放到数组里没办法循环遍历检测每个精灵核心代码如下 <pre&g ...

  9. mgcp的alg功能实现

    刚吃了一碗还算正宗的潮汕牛筋丸粿条和一颗卤蛋,算是给自己的生日礼物. 这一周工作只围绕了一个主题“mgcp的alg功能实现”. 1. 应用场景: 一台运行mgcp语音协议的终端设备,经过一台路由器到达 ...

  10. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

    methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...