1. 程式人生 > >Python設計模式——觀察者模式

Python設計模式——觀察者模式

val property 創建倉庫 tool return observe send als 工作流

例子1:

class Service:
    def __init__(self, service_name, process_name, port, enable_monitor=None):
        self.service_name = service_name
        self.process_name = process_name
        self.port = port
        self.mon = enable_monitor
        self._process_status = True
        self._port_status = True

    @property
    def process_status(self):
        return self._process_status

    @process_status.setter
    def process_status(self, status):
        self._process_status = status
        self.mon.start_mon()

    @property
    def port_status(self):
        return self._port_status

    @port_status.setter
    def port_status(self, status):
        self._port_status = status
        self.mon.start_mon()

class Action:
    @classmethod
    def send_sms_alarm(cls, content):
        print("SMS Alarm: {}".format(content))

    @classmethod
    def send_email_alarm(cls, content):
        print("Email Alarm: {}".format(content))

class Monitor:
    def __init__(self):
        self.services = []

    def add_service(self, service):
        self.services.append(service)

    def start_mon(self):
        for ser in self.services:
            if not ser.process_status:
                Action.send_email_alarm("Service: {0} Process: {1} Status: {2}".format(
                    ser.service_name, ser.process_name, ser.process_status))
            if not ser.port_status:
                Action.send_email_alarm("Service: {0} Process: {1} Status: {2}".format(
                    ser.service_name, ser.port, ser.port_status))

if __name__ == '__main__':
    mon = Monitor()

    http = Service("http", "httpd", 80, mon)
    mysql = Service("mysql", "mysqld", 3306, mon)
    zabbix = Service("zabbix", "zabbixd", 1501, mon)


    mon.add_service(http)
    mon.add_service(mysql)
    mon.add_service(zabbix)

    #mon.start_mon()

    http.port_status = False


例子2:

#coding:utf-8

#Inventory類描述倉庫對象
class Inventory:
    def __init__(self):
        self.observers = [] #此列表用於存儲觀察者對象
        self._product = None #產品
        self._quantity = 0 #數量

    def attach(self, observer): #此方法用於將觀察者對象添加進列表
        self.observers.append(observer)

    @property #使用property裝飾器修飾,使方法變成屬性
    def product(self):
        return self._product

    @product.setter #使用setter修飾product屬性使其可以設置值
    def product(self, value):
        self._product = value
        self._update_observers() #只要設置了產品的值,就調用 _update_observers方法

    @property #對數量的設置
    def quantity(self):
        return self._quantity

    @quantity.setter
    def quantity(self, value):
        self._quantity = value
        self._update_observers() #只要設置了數量的值,就調用 _update_observers方法

    def _update_observers(self):
        for observer in self.observers: #遍歷觀察者對象
            observer() #直接用()號調用觀察者對象,之所以可以直接調用,是因為在ConsoleObserver類中實現了__call__方法

#ConsoleObserver類描述觀察者對象
class ConsoleObserver:
    def __init__(self, inventory):
        self.inventory = inventory

    def __call__(self): #實現__call__方法後可直接可調用,這裏的工作是print了產品和數量信息
        print("product: {0}, quantity: {1}".format(self.inventory.product, self.inventory.quantity))

if __name__ == '__main__':

    i = Inventory() #創建倉庫對象
    c = ConsoleObserver(i) #創建一個觀察者對象,並將倉庫對象作為初始化參數
    i.attach(c) #將觀察者對象添加到倉庫對象中的observers列表裏(兩個對象之間的交互)

    i.product = "Widget" #倉庫對象設置產品名稱(有發生改動)
    i.quantity = 5 #倉庫對象設置產品數量(有發生改動)

    '''
    工作流分析:
        1、首先增加了一個產品名稱,因此通知觀察者打印,此時打印出了新添加的產品名稱,數量默認為0
        2、之後,又增加了數量5,那麽又通知了觀察者,此時打印出了之前添加的產品名稱和這一次新增加的數量5
    '''


Python設計模式——觀察者模式