設計模式Python

面向對象編程的概念

  • 多態
  • 封裝
  • 繼承
  • 抽象
  • 組合

面向對象的設計原則

  • 開放/封閉原則
    對拓展開放,對修改封閉。
  • 控制反轉原則
    基本模塊和從屬模塊機應該有一個抽象層來耦合。
  • 接口隔離原則
    客戶端不應該依賴他不需要使用的接口。
  • 單一職責原則
    類的職責單一,引起類變化的原因單一。
  • 替換原則
    子類應該可以替換基類出現的任何地方。

設計模式的分類

  • 創建型模式
    運行機制基於對象的創建
    例如:單例模式。
  • 結構型模式
    通過組合獲得更加強大的功能的對象和類的結構。
    例如:適配器模式。
  • 行爲型模式
    主要關注對象之間的交互和響應,在交互的時候保持鬆散耦合。
    例如:觀察者模式。

單例模式

  • 理解
    程序運行過程中只能生成一個實例,避免重複浪費公共資源。
  • python實現
# 基於__new__的實現
class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance


s = Singleton()
print(s)
s1 = Singleton()
print(s1)
# 基於metaclass的實現
class MetaSingleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Logger(metaclass=MetaSingleton):
    pass


log1 = Logger()
print(log1)
log2 = Logger()
print(log2)
  • 應用實例
# 說明:避免數據庫連接的時候創建多個對象

import sqlite3


class MetaSingleton(type):
    _instance = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instance:
            cls._instance[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instance[cls]


class Database(metaclass=MetaSingleton):
    connection = None

    def connect(self):
        self.connection = sqlite3.connect('db.sqlite3')
        self.cursor = self.connection.cursor()
        return self.cursor


db1 = Database().connect()
print(db1)
db2 = Database().connect()
print(db2)

monostate(單態)模式

  • 理解:多個實例共享相同的狀態
  • python實現
class Monostate(object):
    __share_state = {}

    def __new__(cls, *args, **kwargs):
        obj = super(Monostate, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls.__share_state
        return obj


s = Monostate()
s.x = 1

s1 = Monostate()
# s的屬性改變,s1的屬性也會隨之改變
print(s1.x)

觀察者模式(監聽者模式)

# 模擬監聽開關按下次數,控制燈光顏色的例子
class Observer:
    """觀察者的基類"""

    def update(self, observer):
        """觀察者接收到通知需要觸發的動作"""
        pass

class Observable:
    """被觀察者的基類"""

    def __init__(self):
        self.__observers = []

    def add_observer(self, observer):
        """增加觀察者"""
        self.__observers.append(observer)

    def remove_observer(self, observer):
        """移除觀察者"""
        self.__observers.remove(observer)
        print('移除觀察者:%s'%observer.__class__.__name__)

    def notify_observer(self, object = 0):
        """狀態改變時通知觀察者"""
        for observer in self.__observers:
            observer.update(self)

class Switch(Observable):
    """開關"""

    def __init__(self):
        super(Switch,self).__init__()
        self.__freq = 0

    def get_freq(self):
        """獲取開關按的次數"""
        return self.__freq

    def set_freq(self, freq):
        """設定開關次數"""
        self.__freq = freq
        print("開關次數:%s"%self.__freq)
        self.notify_observer()


class White(Observer):
    """監聽開關按一下爲白色"""

    def update(self, observable):
        if observable.get_freq() == 1:
            print("我是白色燈")


class Red(Observer):
    """監聽開關按兩下爲紅色"""

    def update(self, observable):
        if observable.get_freq() == 2:
            print("我是紅色燈")



def test_switch():
    """測試觀察者模式"""
    switch = Switch()
    white_mode = White()
    reg_mode = Red()
    switch.add_observer(white_mode)
    switch.add_observer(reg_mode)
    switch.set_freq(1)
    switch.set_freq(2)
    switch.remove_observer(white_mode)
    switch.remove_observer(reg_mode)


if __name__ == '__main__':
    test_switch()     

適配器模式

# 給安卓充電寶增加type-c轉換線
class Battery(object):
    """
    電池
    """

    def __init__(self):
        self.voltage = 0
        self.electric = 0

    def get_voltage(self):
        return self.voltage

    def get_electric(self):
        return self.electric


class AndroidBattery(Battery):
    """
    安卓充電寶
    """

    def __init__(self):
        self.voltage = 5
        self.electric = 2

    def get_line(self):
        return "我是安卓線"


class TypeCAdapter(AndroidBattery, Battery):
    """
    安卓充電線轉type-c轉換器
    """

    def __init__(self):
        self.voltage = 3
        self.electric = 1

    def get_line(self):
        return "我是type-c線"


if __name__ == '__main__':
    print("給小米手機充電")
    xiaomi_charge = AndroidBattery()
    print("充電線", xiaomi_charge.get_line())
    print("電流", xiaomi_charge.get_electric())
    print("電壓", xiaomi_charge.get_voltage(), '\r\n')

    print("給華爲手機充電")
    huawei_charge = TypeCAdapter()
    print("充電線", huawei_charge.get_line())
    print("電流", huawei_charge.get_electric())
    print("電壓", huawei_charge.get_voltage())

待更新……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章