程序設(shè)計(jì)中,為什么要解耦
程序設(shè)計(jì)中,為什么要解耦
此文轉(zhuǎn)載的。覺得非常精辟。
希望對正在學(xué)面向?qū)ο裨O(shè)計(jì)的你有所幫助,總的說來。
有這么多設(shè)計(jì)模式,要用面向?qū)ο?。都是為了解耦。力在降低各模塊的依賴,提高重用。>>>百科>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 在程序設(shè)計(jì)過程中,最頭痛的不是邏輯的編寫過程,更不是算法的設(shè)計(jì),最頭痛的是如何設(shè)計(jì)出一個(gè)容易維護(hù),擴(kuò)展性好的東西。
而耦合問題是最令人煩躁的,它的存在很多人發(fā)現(xiàn)不了,所以往往無從入手,真是有苦自己知了,呵呵。以下是我的經(jīng)驗(yàn)之談。我通過例子來體現(xiàn)耦合問題的影響。
**個(gè)例子: 在開發(fā)游戲的時(shí)候,有很多實(shí)體類,通常屬于一條相同的生產(chǎn)線,如地形:土地,石塊,草地,雪地,沼澤,等,具有相同特征而功能不同的對象,新手們,一般是在程序的某個(gè)地方,默默地new出這些應(yīng)用到的對象,恩,一個(gè),兩個(gè),三個(gè),慢慢你會(huì)發(fā)現(xiàn)程序中不斷出現(xiàn)新對象,如果存在10對象實(shí)體,而對象的提供了5個(gè)接口函數(shù),也就是,讀寫操作,在程序中出現(xiàn)了幾十次,這時(shí),我不要這個(gè)對象了,換成其他了,那你是不是要改幾十處地方?恩,問題就是這里了,沒有一個(gè)抽象層面,必然會(huì)導(dǎo)致維護(hù)困難,當(dāng)對象擴(kuò)大化到100個(gè),這是一個(gè)維護(hù)噩夢,當(dāng)然,單單一個(gè)抽象層面是無法解決new實(shí)體對象的事實(shí)的,這個(gè)是令人頭痛的問題,管理對象的生產(chǎn)是一個(gè)很重要的模塊,這里對于某些高級語言,如C++,**比較好緩解的是工廠模式中的工廠方法,我比較喜歡用這個(gè)模式去管理對象,簡單工廠就不要學(xué)了,沒什么實(shí)際意義,而我可以很明確告訴你,**個(gè)帶你入門,**個(gè)讓你打開眼界的模式**是工廠方法模式,如果真想學(xué)學(xué)模式,請先研究工廠方法,其使用的意義在于把對象的生成延遲到子類,而統(tǒng)一使用接口去管理對象的初始化,把變化點(diǎn)分離出調(diào)用端,這里我只能告訴你為什么要用設(shè)計(jì)模式,什么情況下要用,理不理解就靠你自己的實(shí)際經(jīng)驗(yàn)和悟性了,本人悟性不高,當(dāng)時(shí)在學(xué)習(xí)設(shè)計(jì)模式的時(shí)候,看了很多次依然沒有領(lǐng)悟到工廠模式的奧妙,直至代碼量和項(xiàng)目經(jīng)驗(yàn)不斷地增加才頓悟出過中道理,確實(shí)是很難用文字來表達(dá),不過以上的例子足夠證明它的意義,根源都是為了解耦。第二個(gè)例子: 由于我一直都在開發(fā)游戲,所以所舉得例子不免都和游戲有關(guān),這個(gè)例子,如果你寫過一個(gè)完整的游戲,必然有所了解,游戲總會(huì)有界面,而其中比較典型的界面是,菜單界面,菜單里有按鈕,對吧?恩,這個(gè)問題,我當(dāng)時(shí)設(shè)計(jì)就考慮,菜單類和按鈕類究竟是分開還是合在一起?想來想去,由于當(dāng)時(shí)設(shè)計(jì)觀念沒到家,**把它們合在一起了,這種做法**是不好的,為什么呢?我們不要從概念上入手解釋,通俗的**就是,菜單和按鈕的對應(yīng)關(guān)系是一對多,對吧?沒有一種固定的關(guān)系,有可能1對2,1對3,1對10等等,所以把它們寫在一起,是很僵化的,就單憑這種證明就可以發(fā)現(xiàn),它們要分開,而它們**的表現(xiàn)是合在一起,通過組合的方式,把按鈕的抽象層面注入到菜單里面,就可以動(dòng)態(tài)地生成完整的菜單,所謂的組合方式,不就是,菜單里面有一個(gè)存放按鈕引用的**,希望你明白我所說的,具體我就不解釋了。 結(jié)語:我認(rèn)為這里是全篇文章最重要的,比任何所謂的分層理論都重要,因?yàn)樗ㄋ祝鼘?shí)際,很多人,并不是面向?qū)ο髮W(xué)得不好,但總覺得差什么,我也經(jīng)歷過,面向?qū)ο螅庋b,多態(tài),繼承,學(xué)過的人都知道,都認(rèn)為自己了解了,其實(shí)不然,很多很奇妙的因素,讓你誤解了,大部分的人認(rèn)為封裝很簡單,其實(shí)大錯(cuò)特錯(cuò)了,封裝是最奇妙的,也是最難用好的。
只要你記住以下原則,必然能很好地用好封裝,成員盡量使用protected和private,不要去使用public.盡量不要提供給外部對成員屬性getter的接口,意思就是不要暴露成員,為什么要這樣呢?很簡單,暴露成員屬性必然會(huì)導(dǎo)致自身業(yè)務(wù)的外泄,業(yè)務(wù)外泄,會(huì)導(dǎo)致,類之間的無謂耦合,如A類有成員a,而程序需要對a數(shù)據(jù)改變,而你提供一個(gè)B類可以訪問a成員的getter接口,B類在其自身對a修改,看上去沒什么,實(shí)際上,就是類耦合,對a的修改是類A的職務(wù),由于習(xí)慣的提供getter,導(dǎo)致了,在寫類B的時(shí)候錯(cuò)誤地添加了修改業(yè)務(wù),使類A內(nèi)聚能力降低,程序逐步龐大必然會(huì)越發(fā)明顯,真所謂牽一發(fā)動(dòng)全身,小程序確實(shí)是很難看出問題所在。就寫那么多,本人愚見,希望對你有幫助。
請問安卓里面常說的【解耦和】是什么意思?
這個(gè)是Java里面的一個(gè)理念 面向?qū)ο笏^的解耦是把原來引用很緊密的對象通過中間的一層進(jìn)行分離,不直接引用,可能是只引用接口。這樣感覺起來因?yàn)椴恢苯右?,所以修改起來就好辦多了。
面向?qū)ο蟮奶匦允鞘裁矗?/h3>
在我理解,面向?qū)ο笫窍颥F(xiàn)實(shí)世界模型的自然延伸,這是一種“萬物皆對象”的編程思想。在現(xiàn)實(shí)生活中的任何物體都可以歸為一類事物,而每一個(gè)個(gè)體都是一類事物的實(shí)例。
面向?qū)ο蟮木幊淌且詫ο鬄橹行?,以消息為?qū)動(dòng),所以程序=對象+消息。
面向?qū)ο笥腥筇匦裕庋b、繼承和多態(tài)。 封裝就是將一類事物的屬性和行為抽象成一個(gè)類,使其屬性私有化,行為公開化,提高了數(shù)據(jù)的隱秘性的同時(shí),使代碼模塊化。這樣做使得代碼的復(fù)用性更高。 繼承則是進(jìn)一步將一類事物共有的屬性和行為抽象成一個(gè)父類,而每一個(gè)子類是一個(gè)特殊的父類–有父類的行為和屬性,也有自己特有的行為和屬性。
這樣做擴(kuò)展了已存在的代碼塊,進(jìn)一步提高了代碼的復(fù)用性。 如果說封裝和繼承是為了使代碼重用,那么多態(tài)則是為了實(shí)現(xiàn)接口重用。多態(tài)的一大作用就是為了解耦–為了解除父子類繼承的耦合度。
如果說繼承中父子類的關(guān)系式IS-A的關(guān)系,那么接口和實(shí)現(xiàn)類之之間的關(guān)系式HAS-A。簡單來說,多態(tài)就是允許父類引用(或接口)指向子類(或?qū)崿F(xiàn)類)對象。很多的設(shè)計(jì)模式都是基于面向?qū)ο蟮亩鄳B(tài)性設(shè)計(jì)的。
總結(jié)一下,如果說封裝和繼承是面向?qū)ο蟮幕A(chǔ),那么多態(tài)則是面向?qū)ο笞罹璧睦碚?。掌握多態(tài)必先了解接口,只有充分理解接口才能更好的應(yīng)用多態(tài)。
談?wù)勀銓γ嫦驅(qū)ο笏枷氲睦斫?/h3>
怎么理解面向?qū)ο笏枷肽??面向?qū)ο竺嫦驅(qū)ο缶幊?,即OOP,面向?qū)ο蟮母拍詈蛻?yīng)用已經(jīng)超越了程序設(shè)計(jì)、軟件開發(fā)領(lǐng)域,現(xiàn)在已經(jīng)發(fā)展到了各個(gè)領(lǐng)域。面向?qū)ο罂梢哉f是對現(xiàn)實(shí)世界理解和抽象的方法,是計(jì)算機(jī)編程技術(shù)發(fā)展到一定階段的產(chǎn)物。
它的特點(diǎn):抽象 封裝 繼承 多態(tài)用我的話說,其實(shí)可以這么理解,假如我是上帝,我要造 人 (這是對象)。
首先,我要知道人類要有哪些最基本的東西 ?人要有思想,人還要有肉體這個(gè)過程呢就是(抽象)因?yàn)槿说臄?shù)量很龐大,所以我需要找別人幫我一起造人,但是我不想讓他知道我造人的技術(shù)(人的臉需要用多少克泥巴,需要怎么用手去捏鼻子等等),我可以把我的造人的技術(shù)封裝起來,別人只需要知道他要做什么樣的人類就好了?!痉庋b】當(dāng)我自己造人的時(shí)候,我可能造著造著就累了,我可能就要用我之前造出來的某個(gè)泥人作為模板“**”,“粘貼”了用模板創(chuàng)出來的泥人具有模板的特征,就像孩子一樣具有父母的性狀。我們稱這個(gè)過程為【繼承】但是呢 好多泥人都是我后來偷懶用模板**出來的,為了讓人類更豐富多彩一些,我對他們又進(jìn)行了改變。
解耦的意義何在?
欲速則不達(dá)……編過一定量代碼以后就會(huì)知道為什么有的 APIs 用起來很順手,有的則很別扭……剛開始說不出來什么原因……慢慢的就是有些自己的理解~ 這個(gè)時(shí)候你再看一些軟件工程、UML 或者其他經(jīng)驗(yàn)類的書籍才有可能理解……個(gè)人淺見,千萬不要以為某些概念說說就能理解……比如,你從來沒有用過 C 編寫程序你永遠(yuǎn)不會(huì)理解面向?qū)ο竽男r(shí)候會(huì)比面向過程好用(當(dāng)然,C 語言高手請回避,不需要吐槽)。