Mixin(織入)模式并不是GOF的《設(shè)計模式》歸納中的一種,但是在各種語言以及框架都會發(fā)現(xiàn)該模式(或者思想)的一些應(yīng)用。簡單來說,Mixin是帶有全部實現(xiàn)或者部分實現(xiàn)的接口,其主要作用是更好的代碼復(fù)用。本文將介紹Mixin的應(yīng)用場景,以及關(guān)于繼承、組合、多繼承、接口的一些思考。

 

相關(guān)概念:

  前面提到,Mixin是有部分或者全部實現(xiàn)的接口,其主要作用是代碼復(fù)用,需要理解這個簡單的描述,需要先理清一些概念。

繼承與組合:

  繼承是面向?qū)ο蟮娜筇卣鳎ǚ庋b、繼承、多態(tài)),如果類A繼承自類B,那么我們稱A為子類(派生類),稱B為父類(基類)。什么時候類A才能繼承類B呢,可以說A是B的一種特殊化,英語來說就是A is a B,或者A is a kind of B。比如狗(dog)和動物(Animal)這兩個抽象,dog is animal,這個是成立的,所以dog可以繼承自animal。

  而組合代表的是其中一個類的對象是另一個類的對象的組成組合,英語來說,“has a”,比如人(People)這個類有一個屬性addr是一個地址類(Address)的實例,就是說每個人都有一個地址。

  不管是繼承還是組合,都起到了代碼復(fù)用的作用,但又各有優(yōu)缺點(diǎn)。上面繼承和組合的例子都很明顯,但有些情況就不那么容易區(qū)分兩類事物是繼承還是組合的關(guān)系了,或者說,兩個類之間既可以用繼承,又可以用組合,比如設(shè)計模式中的adapter模式,既可以類適配,又可以組合適配(對象適配)。

 

多繼承與接口:

  在使用編程語言抽象事物之間的繼承關(guān)系的時候,需要考慮對多繼承的實現(xiàn)。所謂多繼承就是說一個類有多個基類,舉個簡單的例子,dog是animal,同時dog又是runnable(可以跑動的對象)。多繼承對于人類的思維來說是比較正常直觀的,但是對于計算機(jī)編程語言,都會遇到一個繞不過去的問題,那就是菱形繼承(diamond problem),下面這個圖形象展示了什么時菱形繼承:

  大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  從上圖可以看到,類B、類C都繼承了類A,類D同時繼承了類B和類C,在繼承關(guān)系上就形成了“菱形”--類D有兩條路徑到達(dá)類A。菱形問題帶來什么問題呢,如果類A定義了某個方法foo,而且B和C都沒有重寫該方法,那么B和C都會有某種機(jī)制找到foo,那么對于D的實例在調(diào)用foo方法的時候,是調(diào)用到B中指向的foo方法還是C中指向的foo方法呢?

  菱形繼承的問題會影響到語言的設(shè)計,一些編程語言支持多繼承,如C++、python等等;另外一些則不支持多繼承,如Java,ruby等。對于支持多繼承的語言,為了解決菱形繼承的問題,一般都會使用特定的方法,比如C++中的虛繼承,python中的新式類的MRO。而對于不支持多繼承的語言,一般使用某種接口(或者約定、協(xié)議)來實現(xiàn)多繼承的功能,如Java中的interface,ruby中的include module。

 

duck typing:

  一個事物是不是鴨子(duck),如果

網(wǎng)友評論