特性和混入不是面向对象的
讓我立刻說,我們將在這里討論的功能是那些迫切需要進(jìn)行放線手術(shù)的人帶給面向?qū)ο缶幊痰募兇獾亩舅?,就像David West在他的《 Objecting Thought》一書中所建議的那樣。 這些功能具有不同的名稱,但最常見的是traits和mixins 。 我很不明白,當(dāng)具有這些功能時(shí),如何仍然可以調(diào)用面向?qū)ο蟮木幊獭?
Terry Gilliam的《拉斯維加斯的恐懼與厭惡》(1998年)
首先,簡而言之就是它們的工作方式。 讓我們使用Ruby模塊作為示例實(shí)現(xiàn)。 假設(shè)我們有一堂課Book :
class Bookdef initialize(title)@title = titleend end現(xiàn)在,我們希望Book類使用一個(gè)靜態(tài)方法(一個(gè)過程)來做一些有用的事情。 我們可以在實(shí)用程序類中定義它,然后讓Book調(diào)用它:
class TextUtilsdef self.caps(text)text.split.map(&:capitalize).join(' ')end end class Bookdef printputs "My title is #{TextUtils.caps(@title)}"end end或者,我們可以使其變得更加“方便”,并extend我們的模塊以便直接訪問其方法:
module TextModuledef caps(text)text.split.map(&:capitalize).join(' ')end end class Bookextend TextModuledef printputs "My title is #{caps(@title)}"end end如果您不了解面向?qū)ο蟮木幊毯挽o態(tài)方法之間的區(qū)別 ,那似乎很好。 而且,如果我們暫時(shí)忘記了OOP的純度 ,即使我的字符較少,這種方法實(shí)際上對我來說也不太可讀。 很難理解caps()方法從何而來,就像#{caps(@title)}而不是#{TextUtils.caps(@title)} 。 你不覺得嗎
當(dāng)我們include它們include進(jìn)來時(shí),Mixins開始發(fā)揮更好的作用。 我們可以將它們結(jié)合起來以構(gòu)造我們要尋找的類的行為。 讓我們創(chuàng)建兩個(gè)mixin。 第一個(gè)稱為PlainMixin ,它將按PlainMixin打印書的標(biāo)題,第二個(gè)稱為CapsMixin ,并大寫已打印的內(nèi)容:
module CapsMixindef to_ssuper.to_s.split.map(&:capitalize).join(' ')end end module PlainMixindef to_s@titleend end class Bookdef initialize(title)@title = titleendinclude CapsMixin, PlainMixindef printputs "My title is #{self}"end end沒有附帶的mixin的Call Book將按原樣打印其標(biāo)題。 添加include語句后, to_s的行為將被覆蓋,方法print產(chǎn)生不同的結(jié)果。 我們可以組合mixin來產(chǎn)生所需的功能。 例如,我們可以再添加一個(gè),將標(biāo)題縮寫為16個(gè)字符:
module AbbrMixindef to_ssuper.to_s.gsub(/^(.{16,}?).*$/m,'\1...')end end class Bookdef initialize(title)@title = titleendinclude AbbrMixin, CapsMixin, PlainMixindef printputs "My title is #{self}"end end我確定您已經(jīng)了解它們都可以訪問Book類的私有屬性@title 。 他們實(shí)際上可以完全使用課堂上的所有內(nèi)容 。 從字面上看,它們是“代碼片段”,我們將其注入到類中以使其更加強(qiáng)大和復(fù)雜。 這種方法有什么問題?
這與注解 , DTO , getter和實(shí)用程序類相同 —它們將對象拆開并將功能塊放置在對象看不到它們的地方。
對于mixin,該功能位于Ruby modules ,該modules對Book的內(nèi)部結(jié)構(gòu)進(jìn)行了假設(shè),并進(jìn)一步假設(shè)程序員在內(nèi)部結(jié)構(gòu)更改后仍將了解Book的內(nèi)容。 這樣的假設(shè)完全違反了封裝的思想。
mixins和對象私有結(jié)構(gòu)之間的這種緊密耦合不會導(dǎo)致無法維護(hù)和難以理解的代碼。
mixin的非常明顯的替代品是可組合裝飾器 。 看一下文章中給出的示例:
Text text = new AllCapsText(new TrimmedText(new PrintableText(new TextInFile(new File("/tmp/a.txt")))) );它看起來與我們上面使用Ruby mixins所做的非常相似嗎?
但是,與mixin不同,裝飾器使對象較小且具有凝聚力,從而在它們之上分層附加功能。 Mixins的作用恰恰相反—它們使對象變得更復(fù)雜,并且因此使對象的可讀性和可維護(hù)性降低。
老實(shí)說,我相信他們只是毒藥。 發(fā)明它們的人距離理解面向?qū)ο笤O(shè)計(jì)的哲學(xué)還有很長的路要走。
您可能還會發(fā)現(xiàn)這些相關(guān)的帖子很有趣: 責(zé)任的縱向與橫向分解 ; 復(fù)合名稱是代碼氣味 ; 不變性的梯度 ; OOP中的反模式 ; 不可變對象如何具有狀態(tài)和行為? ;
翻譯自: https://www.javacodegeeks.com/2017/03/traits-mixins-not-oop.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的特性和混入不是面向对象的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos攻击过程四个组成部分(ddos攻
- 下一篇: 具有ESB,API管理和Now ..服务