設(shè)計(jì)模式 -- 反面模式

反面模式

? ?在軟件工程中,一個(gè)反面模式(anti-pattern或antipattern)指的是在實(shí)踐中明顯出現(xiàn)但又低效或是有待優(yōu)化的設(shè)計(jì)模式,是用來解決問題的帶有共同性的不良方法。它們已經(jīng)經(jīng)過研究并分類,以防止日后重蹈覆轍,并能在研發(fā)尚未投產(chǎn)的系統(tǒng)時(shí)辨認(rèn)出來。

? ?Andrew Koenig在1995年造了anti-pattern這個(gè)詞,靈感來自于GoF的《設(shè)計(jì)模式》一書。而這本書則在軟件領(lǐng)域引入了“設(shè)計(jì)模式”(design pattern)的概念。三年后antipattern因《AntiPatterns》這本書而獲得普及,而它的使用也從軟件設(shè)計(jì)領(lǐng)域擴(kuò)展到了日常的社會互動中。按《AntiPatterns》作者的說法,可以用至少兩個(gè)關(guān)鍵因素來把反面模式和不良習(xí)慣、錯(cuò)誤的實(shí)踐或糟糕的想法區(qū)分開來:

  • 行動、過程和結(jié)構(gòu)中的一些重復(fù)出現(xiàn)的乍一看是有益的,但最終得不償失的模式
  • 在實(shí)踐中證明且可重復(fù)的清晰記錄的重構(gòu)方案

? ?很多反面模式只相當(dāng)于是錯(cuò)誤、咆哮、不可解的問題、或是可能可以避免的糟糕的實(shí)踐,它們的名字通常都是一些用反話構(gòu)成的詞語。有些時(shí)候陷阱(pitfalls)或黑色模式(dark patterns)這些不正式的說法會被用來指代各類反復(fù)出現(xiàn)的糟糕的解決方法。因此,一些有爭議的候選的反面模式不會被正式承認(rèn)。

? ?這個(gè)概念很容易推廣到工程學(xué)以及工程以外需要人們付出努力去爭取的領(lǐng)域。盡管在工程學(xué)以外很少用到這個(gè)術(shù)語,但其概念是通用的。

舉例

社會和組織結(jié)構(gòu)

組織結(jié)構(gòu)

從天而降的責(zé)任(Accidental Ownership):雇員們接手了一個(gè)與當(dāng)前系統(tǒng)完全無關(guān)的系統(tǒng),在沒有合適的訓(xùn)練、學(xué)習(xí)或關(guān)心下就得維護(hù)它

分析癱瘓(Analysis paralysis):花費(fèi)太多精力在項(xiàng)目的分析階段

血刃(Bleeding edge,刀鋒):采用一些未經(jīng)測試和/或尚不穩(wěn)定的前沿技術(shù)來運(yùn)營,從而導(dǎo)致成本超支、表現(xiàn)/性能不佳,和/或交付延期。

搖錢樹(cash cow):盈利的老產(chǎn)品通常會導(dǎo)致對新產(chǎn)品的自負(fù)

委員會設(shè)計(jì)(Design by committee):很多人同時(shí)進(jìn)行設(shè)計(jì),卻沒有統(tǒng)一的看法

承諾升級(Escalation of commitment):明知錯(cuò)了還不能收回之前的決定

獨(dú)裁管理(Management by perkele):用完全聽不進(jìn)異議的獨(dú)裁作風(fēng)進(jìn)行管理

目標(biāo)管理(Management by objectives):通過數(shù)字管理,過于關(guān)注非本質(zhì)而或不易取得的數(shù)字指標(biāo)

道德風(fēng)險(xiǎn)(Moral hazard):不讓做決定的人知道他的決定會帶來什么結(jié)果

蘑菇管理(Mushroom management):不通知或是錯(cuò)誤地通知雇員信息。雇員像蘑菇一樣在黑暗中吸取養(yǎng)分,自生自滅

海鷗式管理(Seagull management):只有當(dāng)出現(xiàn)問題的時(shí)候管理人員才會跟雇員進(jìn)行接觸和互動的管理模式。典型的場景就是,海鷗式的管理人員“飛”過來,嘁嘁喳喳,是人都批評一通,爾后“飛”走了!

煙囪式管理(Stovepipe or Silos,豎井式/發(fā)射井式/谷倉式管理):組織結(jié)構(gòu)是由若干彼此孤立的團(tuán)隊(duì)組成,并且整個(gè)組織結(jié)構(gòu)的范圍內(nèi),上下溝通交流能夠有效進(jìn)行,而水平/橫向的則不然。結(jié)構(gòu)上支持?jǐn)?shù)據(jù)主要在上下方面的流動,卻禁止跨部門的通信。

廠商陷阱(Vendor lock-in,供應(yīng)商套牢,供應(yīng)商陷阱,廠商泥潭):使一個(gè)系統(tǒng)過于依賴于外部所提供的組件/部件。

項(xiàng)目管理

雪崩模型(Avalanche):不合理地混搭或者說混合使用瀑布模型與敏捷開發(fā)方法。

死亡征途(Death march,死亡之旅):除了CEO,每個(gè)人都知道這個(gè)項(xiàng)目會成為一場災(zāi)難,但是真相卻被隱瞞下來,以免項(xiàng)目被立即取消。(盡管CEO通常知道并且仍然繼續(xù)試圖最大化利潤。)然而,真相被隱藏起來,直到大限來臨("Big Bang")。另一種定義:雇員由于不合理的deadline,被迫在深夜和周末加班。

團(tuán)隊(duì)思維(Groupthink):在團(tuán)隊(duì)思維中,團(tuán)隊(duì)成員避免提出在一致觀點(diǎn)之外的思維。

九九定律(Ninety-ninety rule):當(dāng)項(xiàng)目“幾近完成”時(shí),低估完成項(xiàng)目所需時(shí)間的傾向。

過度設(shè)計(jì)(Overengineering):花費(fèi)資源完成比實(shí)際需要的還要魯棒和復(fù)雜的工程

障眼法(Smoke and mirrors):展示還沒實(shí)現(xiàn)的功能,就像它們已經(jīng)實(shí)現(xiàn)了一樣

軟件膨脹(Software bloat):允許系統(tǒng)的后續(xù)版本使用更多的資源

分析方式

旁觀冷漠(Bystander apathy):一個(gè)需求或者設(shè)計(jì)是錯(cuò)的,注意到這一點(diǎn)的人卻不指出,因?yàn)檫@影響的是其他人。

軟件工程

軟件設(shè)計(jì)

抽象倒置(Abstraction inversion):不把用戶需要的功能直接提供出來,導(dǎo)致他們要用更上層的函數(shù)來重復(fù)實(shí)現(xiàn)

用意不明(Ambiguous viewpoint):給出一個(gè)模型(通常是OOAD,面向?qū)ο蠓治雠c設(shè)計(jì))卻沒有指出用意何在

大泥球(Big ball of mud):沒有清晰結(jié)構(gòu)的系統(tǒng)

數(shù)據(jù)庫式進(jìn)程間通信(Database-as-IPC):使用數(shù)據(jù)庫進(jìn)行進(jìn)程間通信,而不使用更輕量級的合適的機(jī)制?;蛘哒f,對于常規(guī)的進(jìn)程間通信,不是去采用輕量得多的合適機(jī)制,而是將數(shù)據(jù)庫用作消息隊(duì)列。

鍍金(Gold plating):在項(xiàng)目達(dá)到最高價(jià)值后還繼續(xù)工作。

內(nèi)部平臺效應(yīng)(Inner-platform effect):系統(tǒng)可自定義的太多,以至于成為一個(gè)軟件開發(fā)平臺的蹩腳的復(fù)制品。

輸入問題(Input kludge):無法確定和實(shí)現(xiàn)對異常輸入的處理

接口膨脹(Interface bloat):把一個(gè)接口做得過于強(qiáng)大以至于極其難以實(shí)現(xiàn)

魔力按鍵(Magic pushbutton):直接在接口的代碼里編寫實(shí)現(xiàn),而不使用抽象

競爭風(fēng)險(xiǎn)(Race hazard):輸出結(jié)果受到事件執(zhí)行順序和時(shí)機(jī)的影響,在多線程環(huán)境和分布式系統(tǒng)中可能發(fā)生

煙囪系統(tǒng)(Stovepipe system):過度聚集數(shù)據(jù)和功能,忽視了與其他系統(tǒng)和模塊的共享

面向?qū)ο笤O(shè)計(jì)

貧血的域模型(Anemic Domain Model):僅因?yàn)槊總€(gè)對象都要有屬性和方法,而在使用域模型的時(shí)候沒有加入非OOP的業(yè)務(wù)邏輯

(BaseBean):繼承一個(gè)工具類的功能,而不是委托給它

調(diào)用父類(Call super):需要子類調(diào)用父類被重定義的方法

圓還是橢圓問題(Circle-ellipse problem):基于變量的子類化關(guān)系進(jìn)行子類化

循環(huán)依賴(Circular dependency):在對象或軟件模塊中,直接或間接引入循環(huán)依賴。

常量接口(Constant interface):使用接口定義常量

上帝對象(God object):在設(shè)計(jì)的單一部分(某個(gè)類)集中了過多的功能

對象糞池(Object cesspool):復(fù)用那些不滿足復(fù)用條件的對象。對象池是一種管理對象的方法,在重復(fù)使用對象前,需要針對對象進(jìn)行初始化,以避免上次使用后的狀態(tài)等數(shù)據(jù)影響下次的使用

不羈的對象(Object orgy):沒有成功封裝對象,外部可以不受限制地訪問它的內(nèi)部

幽靈(Poltergeists):指這樣一些對象,它們唯一的作用就是把信息傳給其它對象

順序耦合(Sequential coupling):指這樣一些對象,它們的方法必須要按某種特定順序調(diào)用

悠悠問題(Yo-yo problem):一個(gè)結(jié)構(gòu)(例如繼承)因?yàn)檫^度碎片化而變得難于理解編程

偶然復(fù)雜度(Accidental complexity):向一個(gè)方案中引入不必要的復(fù)雜度

遠(yuǎn)隔作用(Action at distance):意料之外的在系統(tǒng)分離的部分之間交互

盲目信任(Blind faith):缺乏對bugfix的校驗(yàn)或?qū)ψ雍瘮?shù)返回值的正確性檢查

船錨(Boat anchor):在系統(tǒng)中保留無用的部分

忙等待(Busy waiting):在等待的時(shí)候不斷占用CPU,通常是因?yàn)椴捎昧酥貜?fù)檢查而不是適當(dāng)?shù)南C(jī)制

緩存失敗(Caching failure):錯(cuò)誤被修正后忘記把錯(cuò)誤標(biāo)志復(fù)位

拜物編程(Cargo cult programming):由于對模式的盲目崇拜,在不理解的情況下就使用模式和方法,企圖得到好的結(jié)果

靠異常編程(Coding by exception):當(dāng)有特例被發(fā)現(xiàn)時(shí)才添加新代碼去解決

隱藏錯(cuò)誤(Error hiding):在顯示給用戶之前捕捉到錯(cuò)誤信息,要么什么都不顯示,要么顯示無意義的信息

硬編碼(Hard code):將對系統(tǒng)環(huán)境的假設(shè)寫入實(shí)現(xiàn)中

熔巖流(Lava flow):保留不想要的(冗余的或是低質(zhì)量的)代碼,僅因?yàn)槌ミ@些代碼的代價(jià)太高或是會帶來不可預(yù)期的結(jié)果

循環(huán)-switch序列(Loop-switch sequence)在循環(huán)結(jié)構(gòu)中使用switch語句來編寫連續(xù)步驟

魔術(shù)數(shù)字(Magic numbers):在算法里直接使用數(shù)字,而不解釋含義

魔幻字符串(Magic strings):直接在代碼里使用常量字符串,例如用來比較,或是作為事件代碼

自我復(fù)制(Repeating yourself):通過不斷復(fù)制已有代碼的模式或代碼段進(jìn)行編碼;而非采用once and only once(抽取原則)

軟代碼(Soft code):在配置文件里保存業(yè)務(wù)邏輯而不是在代碼中

面條代碼(Spaghetti code):指那些結(jié)構(gòu)上完全不可理解的系統(tǒng),尤其是因?yàn)檎`用代碼結(jié)構(gòu)

霰彈槍手術(shù)(Shotgun surgery):開發(fā)人員一次性在一個(gè)多個(gè)實(shí)現(xiàn)的代碼基中增加功能方法論

拷貝粘貼編程(Copy and paste programming):拷貝(然后修改)現(xiàn)有的代碼而不是構(gòu)造通用的解決方案

黃金大錘(Golden hammer):認(rèn)為自己最喜歡的解決方案是到處通用的(參見:銀彈)

不可能因素(Improbability factor):認(rèn)為已知的錯(cuò)誤不可能發(fā)生

非我所創(chuàng)(Not invented here):拒絕使用組織外的主意或方案,但這也可能是出于版權(quán)等原因

這里發(fā)明的(invented here):拒絕組織內(nèi)部實(shí)現(xiàn)的創(chuàng)新或解決方案,通常因?yàn)閷Τ蓡T沒有信心

不成熟的優(yōu)化(Premature optimization):在編碼的早期追求代碼的效率,犧牲了好的設(shè)計(jì)、可維護(hù)性、有時(shí)甚至是現(xiàn)實(shí)世界的效率

轉(zhuǎn)換編程法或巧合編程(Programming by permutation or programming by accident):試圖通過連續(xù)修改代碼再看是否工作的方式來解決問題

重新發(fā)明方的輪子(Reinventing the square wheel):已經(jīng)有一個(gè)很好的方案了,又再搞一個(gè)爛方案來替代它

銀彈(Silver bullet):認(rèn)為自己最喜歡的技術(shù)方案能解決一個(gè)更大的問題

測試人員驅(qū)動開發(fā)(Tester driven development):需求來自bug報(bào)告的軟件工程

殞石式驅(qū)動開發(fā)(Meteorite driven development):需求來自任性的不具備專業(yè)知識及尊重的上層,以犧牲底層員工生活品質(zhì)及削弱精神為主軸的開發(fā)方式,需求如隕石一般來自天上而不可回避配置管理

依賴地獄(Dependency hell):所依賴產(chǎn)品的版本所導(dǎo)致的問題

DLL地獄(DLL hell):不同版本DLL所帶來的問題,包括DLL可見性和多版本問題,在微軟的Windows上尤為突出

擴(kuò)展沖突(Extension conflict):蘋果系統(tǒng)在Mac OS X版本之前的不同擴(kuò)展的問題

JAR地獄(JAR hell):JAR文件不同版本或路徑帶來的問題,通常是由于不懂類加載模型導(dǎo)致的


學(xué)習(xí) 設(shè)計(jì)模式 中無意 看到,覺得比較有意思,故摘要于此,以上內(nèi)容摘自維基百科

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容