暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OOP设计模式Python实现--行为型模式之状态模式

稻壳编程 2021-02-08
169

作者简介

211工程院校贵州大学管理学院硕士研究生、互联网金融行业资深DevOps研发工程师. 曾在国内多家知名互联网公司 平安科技、微众银行、顺丰科技、魅族任职. 具有多年国内一线互联网公司自动化运维平台设计与开发经验。



OOP设计模式Python实现

行为型模式--状态模式

前言:

行为型模式是对在不同的对象之间划分责任和算法的抽象化;在系统运行时,对象并不是孤立的而是通过相互通信与协作完成复杂功能的,也就是一个对象在运行时也将影响到其他对象的运行。在状态模式中随着对象内部的状态发生改变对象执行不同的流程,也就是类的行为是基于它的状态改变的。在代码开发过程中,会根据不同的情况作出不同的处理,最直接的解决方案是将这些所有可能发生的情况全都考虑到,使用if... else...条件控制语句进行状态判断来处理不同的情况,这样的代码在面临复杂的状态判断时就会显得"力不从心"。随着状态的增加或减少,就意味着if...else..语句将会随之进行修改,导致代码的可读性、扩展性变弱,维护也会很麻烦。状态模式通常在代码逻辑中包含大量与对象状态相关的条件控制语句时使用。

 1 

白话状态模式

监控Agent对Linux服务器的性能指标进行采集,并将获取到的数值与指标阈值相比对,进而采取不同的告警策略,本文分别通过Python与Golang语言来实现状态模式,代码结构图如下所示:



 2 

示例代码(未使用状态模式)

    class Low:
    def do_execute(self):
    print("服务器负载较低..不做任何操作...")


    class Meduim:
    def do_execute(self):
    print("服务器负载较高..发送电子邮件...")


    class Large:
    def do_execute(self):
    print("服务器负载较高..发送电子邮件...发送短信...")


    def client(value):
    if value >= 0 and value < 30:
    Low().do_execute()
    elif value >= 30 and value < 70:
    Meduim().do_execute()
    elif value >= 70 and value < 100:
    Large().do_execute()
    else:
    print("unknown..")


    if __name__ == '__main__':
    client(20)
    print("##" * 10)
    client(70)

    输出:

      服务器负载较低..不做任何操作...
      ####################
      服务器负载较高..发送电子邮件...发送短信...

       3 

      示例代码(应用状态模式)

        #!/usr/bin/python
        #coding:utf-8
        from abc import ABCMeta, abstractmethod
        class State(metaclass=ABCMeta):
        @abstractmethod
        def Handle(self, *args, **kwargs):
                pass
                
        class Low(State):
        def Handle(self, context):
        if context.value >= 0 and context.value < 30:
        print("阈值未触发告警..")
        else:
        context.state = Medium()
        context.Request()
                    context.state = self
                    
        class Medium(State):
        def Handle(self, context):
        if context.value >= 30 and context.value < 70:
        print("阈值触发告警.. 发短信...")
        else:
        context.state = Large()
        context.Request()
                    context.state = Low()
                    
        class Large(State):
        def Handle(self, context):
        if context.value >= 70 and context.value < 100:
        print("阈值触发告警.. 发短信.. 发微信..")
        else:
        print("未能正确识别的阈值..")


        class Context:
        def __init__(self):
        self.__state = Low()


            @property
        def state(self):
        return self.__state
        @state.setter
        def state(self, s):
        self.__state = s


        @property
        def value(self):
                return self.__value    
        @value.setter
        def value(self, v):
        self.__value = v


        def Request(self):
        self.__state.Handle(self)


        if __name__ == '__main__':
        c = Context()
        c.value = 20
        c.Request()
        print("###")
        c = Context()
        c.value = 50
        c.Request()
        print("###")
        c = Context()
        c.value = 80
        c.Request()
            print("###")

        输出:

          阈值未触发告警..
          ###
          阈值触发告警.. 发短信...
          ###
          阈值触发告警.. 发短信.. 发微信..
          ###


           4 

          Golang实现状态模式

            package main
            import "fmt"


            type State interface{
            Handle(Context)
            }


            type Low struct {}
            func (s *Low) Handle(c Context){
            if c.value >= 0 && c.value < 30{
            fmt.Println("阈值过低. 未触发告警..")
            }else{
            c.set_state(new(Medium))
            c.Request()
            c.set_state(s)
            }
            }




            type Medium struct {}
            func (s *Medium) Handle(c Context){
            if c.value >= 30 && c.value < 70{
            fmt.Println("阈值过高. 发送告警..")
            }else{
            c.set_state(new(Large))
            c.Request()
            c.set_state(new(Low))
            }
            }


            type Large struct {}
            func (s *Large) Handle(c Context){
            if c.value >= 70 && c.value < 100{
            fmt.Println("阈值过低. 发送告警..发送短信")
            }else{
            fmt.Println("不知道嗯么做")
            }
            }




            type Context struct{
            value int
            state State
            }


            func (c *Context) set_value(v int){
            c.value = v
            }




            func (c *Context) get_value() int {
            return c.value
            }


            func (c *Context) set_state(v State){
            c.state = v
            }


            func (c *Context) get_state()State{
            return c.state
            }


            func (c *Context) Request(){
            c.state.Handle(*c)
            }


            func NewContext() *Context{
            state := new(Low)
            return &Context{state: state}
            }


            func main(){
            c := NewContext()
            c.value = 20
            c.Request()
            fmt.Println("#####")


            c.value = 40
            c.Request()
            fmt.Println("##")


            c.value = 80
            c.Request()
            fmt.Println("###")
            }
            输出:
              阈值未触发告警..
              ###
              阈值触发告警.. 发短信...
              ###
              阈值触发告警.. 发短信.. 发微信..
              ###


               5 

              结束语

              如果本文可以对您的工作学习带来帮助,请扫描左侧赞赏码以资鼓励作者;文章勘误请扫描右侧二维码联系作者。


              文章转载自稻壳编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论