Python之MVC

這杯可樂有點甜發表於2019-02-16

了幾個小專案,在幫助同事的時候發現,每個人對MVC這種設計模式的理解各有千秋。
我對於MVC的理解是M即Model,指的是資料庫層面,V即View,指的是檢視層面,至於C即Control,則是程式碼的邏輯部分。
專案背景介紹,使用QT5寫Gui,Mysql作為資料庫。
我採用C繼承V,M繼承C的模式來實現MVC。view層是將QT生成的ui檔案轉化成python程式碼,不直接修改view層的程式碼;model實現對資料庫的CRUD操作,並return。control作為中間層,呼叫model層的方法獲取結果,完成邏輯功能,再傳遞給view層實現資料渲染。

# view.py
class View(QDialog):
    pass
    
    def render_view(self, data):
        # render view
        pass

# control.py    
class Control(View):
    pass
    
    def do_something(self):
        data = self.get_data()
        self.render_view(data)
    
# model.py  
class Model(Control):
    pass
    
    def get_data(self):
        return `something`

由於model層繼承於control層,當我呼叫model層,也就是control的子類的方法時,它是不存在的,所以我得先宣告一個空方法。

#control.py    
class Control(View):
    pass
    
    def do_something(self):
        data = self.get_data()
        self.render_view(data)
        
    def get_data(self):
        pass

但達到一定量的程式碼量時,發現control層的pass方法(方法體內只有pass)越來越多,覺得這樣不妥呀~,而且當我要測試資料庫互動是否正常時,也就是測試model層的程式碼,總是會彈出它爸爸的爸爸,也就是view層寫的Gui,導致感覺非常難受。

於是乎,選擇重構,前後花了兩週不到的時間,複用了部分邏輯,程式碼從18K+降到了11K左右。
我選擇將model層作為一個部件類,裝配到control層,原先的view和control的關係不變。

# view.py
class View(QDialog):
    pass
    
    def render_view(self, data):
        # render view
        pass

# control.py    
class Control(View):
    def __init__(self):
        super().__init__()
        self.model = Model()
        pass
    
    def do_something(self):
        data = self.model.get_data()
        self.render_view(data)
    
# model.py  
class Model(object):
    pass
    
    def get_data(self):
        return `something`

這樣處理後,我的model層至此和邏輯徹底分離,測試資料庫互動方便多了,直接在model層下寫個main方法就可以了,而且針對control層可以進行復用,也就是在相同Gui下,我可以在control層例項化多個不同的model,根據業務需要呼叫不同的model,提升程式碼的複用率。

哇咔咔~~

相關文章