一、前言
什么是可插拔式設計?
在我們前面學習的django的內容,在django框架中,我們學習到了中間件,中間件是干嘛的,都還記得把!!
中間件是當請求來的時候,全局的對每一個request進行一個驗證,我們都知道在Django的中間件中,有7個默認的中間件,而當一個request來的時候,這個request要依次經過每一個中間件的校驗,當這個request對應的response走的時候,又要按照中間件列表的順序進行倒敘執行中間件
在我們最開始用form表單提交數據的時候,我們好像是要把一個叫csrf的中間件給注釋掉,然后form表單才能去提交post請求,也就是說當注釋掉這個叫csrf的中間件的時候,request請求來的時候,這個request就不會經過這個中間件的校驗了,而當我們把這個csrf的中間件注釋解開的時候,我們發現request請求有經過這個中間件的校驗了。這就叫可插拔式設計
二、可插拔式需要用到的方法
1. 可插拔式設計的代碼,一定要是面向對象的
2.用到一個
3.用到反射getattr()
三、實例
我們現在有一個公司,現在公司有一個需求,因為今天是10月的最后一天,公司准備給每一個工作人員通過qq、手機短信、微信的方式,給工作人員發三太難短信,
然后,到11月份的月底,公司只想通過微信,qq的方式來發送信息了,這該怎么樣設計一個可插拔是的程序呢?---根據django中間件的思想
1.我們先用面向對象來寫着三個發消息的共功能
# 面向對象的鴨子類型
# 只要長得像,就是鴨子類型
# 就是有很多個類,但是這些個類都具有同樣的方法名,但是呢?它的方法名實現的功能不一樣,就是鴨子類型
# QQ 消息
class QQ:
# 實例化類的時候觸發
def __init__(self,name):
self.name = name
# 對象的綁定方法
# 也是鴨子類型的方法
def send_msg(self,content):
print('QQ今天是10月的最后一天,請好好{}'.format(content))
# 微信 消息
class Wechat:
# 對象實例化的時候觸發
def __init__(self,name):
self.name = name
# 鴨子類型的方法,對象的綁定方法
def send_msg(self,content):
print('Wechat今天是10月的最后一天,請好好{}'.format(content))
# Phone 短信
class Phone:
def __init__(self,name):
self.name = name
# 鴨子類型
def send_msg(self,content):
print('Phone今天是10月的最后一天,請好好{}'.format(content))
從上面我們寫的類中,三種發送消息的類,可以看到send_msg就是鴨子類型的方法,
我們將上面的每一個類都放在不同的.py文件里
為什么放在一個包里呢?因為在settings配置里面。我們要導入這幾個文件,導入一個文件他就是一個模塊,那作為一個模塊,當然要放在包里了,__init__.py文件里,from msg_bag import *
那這三個類都寫好了,我們知道django中間件是則settings里配置了一個列表,這個列表就是放着一個個字符串一行的類,
那這里,我們也將這三個類放在setting文件中,當然首先的自己新建一個settings配置文件啦
# settings.py
FUNC_LIST = [
'msg_bag.phone.Phone',
'msg_bag.qq.QQ',
'msg_bag.wechat.Wechat',
]
# 啟動文件
import setting # 將配置文件導進來
import importlib # 將這個模塊導入
def run(content):
# 循環settings配置文件里的類的模塊列表
'''
FUNC_LIST = [
'msg_bag.phone.Phone',
'msg_bag.qq.QQ',
'msg_bag.wechat.Wechat',
'''
for func in setting.FUNC_LIST:
# 將每一個字符串拿出來,然后根據.切割,從末尾切割一個
model,class_name = func.rsplit('.',maxsplit=1)
print(model) # msg_bag.phone \ msg_bag.qq \ msg_bag.wechat
print(class_name) # Phone \ QQ \ Wechat
# 利用importlib模塊
mod = importlib.import_module(model)
'''
等同於
form msg_bag import phone
form msg_bag import qq
form msg_bag import wechat
'''
# 通過反射class_name是不是mod的類,然后取值賦給class_obj
class_obj = getattr(mod, class_name)
# 通過類去調用對象的綁定方法,將類自己傳給send_msg
class_obj.send_msg(class_obj,content)
run('開開心心')