文章同步更新於:blog.dalao.icu/archives/33.html,請訪問該博客獲得更好的閱讀體驗。
1.什麼是Mixin設計模式
mixin
設計模式可以看做是多繼承的一種。那麼首先,咱們談談爲什麼會出現多繼承這種語法。
汽車和飛機他們都同屬於交通工具,但飛機可以飛行,汽車無法做到,所以,飛行這個行爲不能寫到交通工具這個類中,如果每一個交通工具各自實現自己的行駛方法,就違背了代碼儘可能重用的原則(如果交通工具種類越來越多,就會造成大量代碼冗餘)。
所以,我們要表示飛行這個行爲,就需要進行多繼承。但這樣,我們就違背了繼承關係必須是is-a
原則。
在java中,雖然沒有多繼承,但我們可以通過interface
來實現多繼承。
在python中,沒有interface
這一語法,但它本身是支持多繼承的。
在使用多繼承的時候,很容易就會設計不當,導致繼承鏈混亂,影響mro
查找,所以,在編程的時候我們的原則就是,能使用其他方法代替多繼承就儘量不適用多繼承。
這個時候Mixin
設計模式就應運而生,Mixin
直譯理解就是混入、補充的意思,它是多繼承的一種。在多繼承中,查找順序是按mro
繼承鏈中的順序進行的。
這樣一來,我們不需要複雜而龐大的繼承鏈,只要選擇組合不同的類的功能,就可以快速構造出所需的子類。
2.Mixin設計模式實例
class Vehicle:
pass
class PlaneMixin:
def fly(self):
print("Flying")
class Airplane(Vehicle, PlaneMixin):
pass
可以看到,上述代碼中,Airplane
類實現了多繼承,在繼承鏈上,它繼承了Vehicle
類和PlaneMixin
類,這裏我們遵循Mixin
設計模式的要求,在後面添加上後綴Mixin
增強代碼的可讀性。
上述代碼可以這麼理解,Airplane
只是一個Vehicle
類,而不是Plane
類,而Mixin
後綴,它告訴其他讀者,這個類是作爲功能添加到子類中的,並不是作爲父類,它的作用等同於Java中的interface
。
3. 使用Mixin設計模式的原則
在使用Mixin
設計模式實現多重繼承的時候要特別注意下列幾點原則:
- 首先,Mixin類必須表示某一種功能,而不是某一個物體,這點跟java中的
Runnable
和Callable
是一樣的。 - 其次,它表示的責任必須單一,如果有多個功能,我們應該去實現多個
Mixin
類。 - 接下來,Mixin類不依賴於子類的實現,且屬於抽象類,本身不能實例化,也不能繼承Mixin以外的類。
- 最後,子類即使沒有繼承Mixin類,也必須照常工作,只是部分功能缺少無法使用。
Java的接口,只提供了“規格”的多重繼承。Mixin類則同時提供了“規格”和“實現”的多重繼承,使用上相比接口會更加簡單。
4. 補充
在其他框架或者語言中,也有類似的Mixin功能,如Ruby
,Django
,Vue
, React
等等。