一、什麼是面向對象 在用面向對象思想寫代碼之前,先瞭解一下什麼是面向對象? 個人理解: 面向對象:把現實世界里的具體物體或者邏輯世界的邏輯物體,用抽象手段,把這些物體抽象成程式能夠識別的類,使類具備物體的屬性和行為,把物體與物體之間的關聯轉換成類與類之間的關聯,用編程邏輯把這些關聯表示出來設計成程式 ...
一、什麼是面向對象
在用面向對象思想寫代碼之前,先瞭解一下什麼是面向對象?
個人理解:
面向對象:把現實世界里的具體物體或者邏輯世界的邏輯物體,用抽象手段,把這些物體抽象成程式能夠識別的類,使類具備物體的屬性和行為,把物體與物體之間的關聯轉換成類與類之間的關聯,用編程邏輯把這些關聯表示出來設計成程式,也就是面向對象設計。
什麼樣的設計才是面向對象的呢:
符合封裝、繼承、多態特征的設計
為什麼要用面向對象:
通過定義我們知道面向對象是用來解決物體與物體之間的關聯的一種方式,除了這種方式還有很多其他方式比如面向過程。解決問題的方式很多,但是最好的只有一個,在代碼的世界里我們不僅要考慮功能的實現,還要考慮後期的維護,用面向對象的思想編寫代碼比其它方式,能讓程式更好的維護。
二、如何用面向對象思想編寫代碼
抽象-----實現面向對象思想設計程式
如何抽象,抽象層次:
第一層 抽象 :把現實世界存在的物體或者邏輯物體通過抽象封裝成一個具體類,體現了面向對象封裝特征,如下圖
這兩個類把現實世界具體動物轉換成程式里的具體類或者實例類
第二層 抽象 : 第二層抽象是必須的嗎,不是的,因為第一層中不同的具體類之間有相同或相似部分,又有不同的部分,它們之間有聯繫,好像是一個事物呈現了多種形態,也就是一個事物有變化,才會有第二層抽象出現
此時我們需要抽象出來相似部分,去封裝成一個對象,然後被子類繼承,這也體現了面向對象繼承特征,子類中的方法也體現了面向對象多態特征,如下圖
可能有人會問Car里和Cat里都有Run有相似部分不也可以抽象嗎,我們不能這樣做,因為現實世界Cat和Car之間沒有任何聯繫,而面向對象只能抽象現實世界或或邏輯世界有關聯的對象,然後解決這些關聯對象間的邏輯處理。
Cat和Car雖然有相似部分但是沒有關聯關係也就不存在邏輯關係,抽象在一起也沒啥意義。
所以第二層抽象關鍵點在於判斷具體對象間是否有關聯關係或邏輯關係-----通過現實世界物體間是否有關聯關係來決定具體對象是否有關聯關係
Cat和Bird在現實世界都屬於動物,他們之間是有關聯的。
第三層 抽象 : 對第二層抽象出來的相似部分進一步抽象。大家都知道相似部分是子類共用的一但變化所有的子類都將受到影響,此時我們需要對相似部分做抽象分離,通常把狀態相關和行為相關分離,行為穩定的和行為不穩定的分離,粒度越細越好。
粒度越細複雜度越高,此時需要複雜度和穩定性之間找個平衡點。
第四層 抽象: 對子類變化進行抽象,相似的部分我們封裝了,針對變化的部分,此時會考慮一些設計模式,來解決子類的變化問題,比如某個方法的內部實現用策略模式等。一般解決類結構變化是新增介面文件,解決類狀態變化或者行為邏輯的變化直接修改即可。
一般抽象到這一層應該就滿足需求了。
第五層 抽象:
......
第N層 抽象:最後每一個對象都符合面向對象的設計原則
三、如何判斷一個對象是否合理
1、 如果對象只有一種呈現形態:也就是說程式里無論是什麼時候我們就只使用對象一種實例,這個對象只要符合單一職責的原則就好了,不用再去抽象
2、 如果對象有多種呈現形態:也就是說程式里我們根據不同的情景或者上下文會使用對象的不同呈現形態(實例),這個對象除了滿足單一職責,還要考慮這個對象是否符合其它設計原則
四、面向對象的設計原則
為了讓文章更完整我就補上了,很多博文都有講解
1、SRP-Single Responsibility Principle 單一職責原則
2、OCP-Open Close Principle 開閉原則
3、LSP-Liskov Substitution Principle 里氏替換原則
4、DIP-Dependence Inversion Principle 依賴倒置原則
5、ISP-Interface Segregation Principle 介面分離原則
6、LOD-Law Of Demeter 最少知識原則(迪米特原則)
7、CARP-Composite/Aggregate Reuse Principle 優先復用原則
這些設計原則是為了判斷抽象出來的對象是否合理,也就是說判斷創建的類是否合理。程式符合這些原則就更加符合面向對象設計。
單一職責原則是每個對象每個類需要滿足的最基本原則,下麵也談下自己的理解
五、單一職責原則
職責是指類變化的原因。如果一個類有多於一個的動機被改變,那麼這個類就具有多於一個的職責。而單一職責原則就是指一個類或者模塊應該有且只有一個改變的原因。
為什麼出現這一原則呢?我們經常會遇到以下情景:
T負責兩個不同的職責:職責P1,職責P2,當由於職責P1需求發生改變而需要修改類T時,有可能會導致原本運行正常的職責P2功能發生故障,也就是說職責P1和P2被耦合在了一起,導致程式很脆弱
作用:單一職責用來給對象瘦身的,類的結構瘦身,類的細節瘦身,把不屬於它的職責徹底剝離
它包含兩層意思:
1、一個類只負責做屬於它自己的事
2、引起一個類變化的原因只能有一個,就是屬於這個類的職責需求變化了
單一職責不是說一個類只做一件事,這個類可以做多件事情,但是這些事情需要都屬於這個類的職責,也就是說只做它該做的,不該做的就剝離。
如何判斷一個類是否多於一個職責:
1、Information holder –該對象設計為存儲對象並提供對象信息給其它對象。
2、Structurer –該對象設計為維護對象和信息之間的關係
3、Service provider –該對象設計為處理工作並提供服務給其它對象
4、Controller –該對象設計為控制決策一系列負責的任務處理
5、 Coordinator--該對象不做任何決策處理工作,只是delegate工作到其它對象上
6、Interfacer--該對象設計為在系統的各個部分轉化信息(或請求)
一個對象應該有且只有一個上面的職責
六、總結
面向對象整體設計思路:抽象---->具體對象---->變化---->對象的多種呈現形態---->抽象---->抽象---->符合設計原則---->單一職責具體對象
面向對象核心:針對變化進行抽象封裝
備註:如若轉載請說明文章出處