面向?qū)ο?/h1>
面向?qū)ο缶幊蹋∣OP)
面向?qū)ο缶幊蹋菏且环N編程范式,它以類和對象作為組織代碼的單元,以封裝、抽象、繼承、多態(tài)四大特性作為代碼設計和實現(xiàn)的基石。注意:面向?qū)ο缶幊谈雨P注組織代碼的單元是否為類或?qū)ο蟮姆绞?/strong>,即使編寫的代碼中沒有全部引用四大特性也是面試對象編程。
面向?qū)ο缶幊陶Z言(OOPL)
面向?qū)ο缶幊陶Z言是支持類或?qū)ο蟮恼Z法機制,并有現(xiàn)成的語法機制,能方便地實現(xiàn)面向?qū)ο缶幊趟拇筇匦裕ǚ庋b、抽象、繼承、多態(tài))的編程語言。
面向?qū)ο蠓治?OOA)、設計(OOD)
面向?qū)ο蠓治龅哪康氖歉闱宄鍪裁?;面向?qū)ο笤O計是搞清楚怎么做;面向?qū)ο缶幊淌菍烧叩慕Y果(類的設計)翻譯成代碼,三種正好對應軟件開發(fā)的三個階段;
四大特性及其作用
封裝
目的:信息隱藏、數(shù)據(jù)保護。
要求:編程語言提供權限訪問控制語法來支持,如public 、private等關鍵詞。
意義:一方面:保護數(shù)據(jù)不被任意修改,提高了代碼的可維護性;另一方面:僅暴露有限的必要接口,提高了代碼的易用性。
抽象
目的:隱藏方法細節(jié),使調(diào)用者關注方法的功能。
要求:抽象通過接口類或者抽象類來實現(xiàn),不需要特殊的語法機制來支持。
意義:一方面是提高代碼的可擴展性、維護性,修改實現(xiàn)不需要改變定義,減少代碼的改動范圍;另一方面,它也是處理復雜系統(tǒng)的有效手段,能有效地過濾掉不必要關注的信息。
繼承
定義:表示 is-a 關系,分為單繼承和多繼承;Java為單繼承。
要求:編程語言需要指出繼承的特性,如Java 的 ”extends“。
意義:解決代碼復用性。
多態(tài)
定義:多態(tài)是指子類替換父類,調(diào)用子類的方法實現(xiàn)。
要求:編程語言需要具備繼承和抽象的語法支持,如Java中的繼承/接口 + 方法重寫的組合。
意義:提高代碼的擴展性和復用性,是很多設計模式、設計原則、編程技巧的代碼實現(xiàn)基礎。
面向過程
面向過程編程
面向過程編程:相較于面向?qū)ο缶幊桃灶悶榛镜木幊虇卧?,面向過程是以方法作為編程的基本單元,她最大的特點是數(shù)據(jù)和方法分離,且不支持豐富的面向?qū)ο缶幊烫匦裕ǚ庋b、繼承、多態(tài))。
面向?qū)ο蠛兔嫦蜻^程比較
面向?qū)ο缶幊滔噍^于面向過程編程來說主要有三大優(yōu)勢:
- 支持豐富的面向?qū)ο缶幊烫匦?,利用這些特性編寫的代碼,更易復用、擴展和維護。
- 對于大規(guī)模復雜程序的開發(fā),程序的處理流程并非單一主線,而是復雜的網(wǎng)狀結構,因為面向?qū)ο缶幊淌腔陬愖鳛榫幊虇卧M行編程,所以更適用這種復雜類型的開發(fā)。
- 從編程語言和機器打交道的情況來看,面向?qū)ο缶幊瘫让嫦蜻^程編程更加高級、更加人性化。
面向過程編程相較于面向?qū)ο缶幊虂碚f主要的優(yōu)勢:從和機器適配的情況來看,面向過程編程相較于面向?qū)ο缶幊虛碛懈玫倪m配性,所以相應的執(zhí)行效率更高。
面向?qū)ο缶幊讨心男┰O計實際上是面向過程的
-
濫用getter、setter方法 -- 違反了封裝特性
getter、setter方法的設計初衷是:對類屬性進行保護,通過暴露有限的getter、setter方法作為外面客戶訪問入口;
所以在設計類的時候,除非真的需要否則盡量不要給屬性定義setter方法;屬性如果屬是容器類,定義getter方法的時候也需要防范容器內(nèi)部數(shù)據(jù)被修改的風險。
public class ShoppingCart { private int itemsCount; private double totalPrice; private List<ShoppingCartItem> items = new ArrayList<ShoppingCartItem>(); public List<ShoppingCartItem> getItems() { return items; } public static void main(String[] args) { ShoppingCart cart = new ShoppingCart(); //外部代碼還是能修改 items 中的數(shù)據(jù) cart.getItems().clear(); } } public class ShoppingCartItem{ }
-
Utils類、Constants類設計問題
Constants類、Utils類作用:解決代碼復用問題;對于這兩類的設計,我們盡量做到職責單一,盡量定義一下細化的小類,如DataSourceConstants類,不要定義大而全的類(定義大而全的類容易造成代碼的維護性下降、編譯時間過長、代碼開發(fā)易沖突和代碼復用性問題),除此之外,如果能將這些類中的屬性和方法劃歸到業(yè)務類最好不過,這樣可以極大提供類的內(nèi)聚性和代碼的復用性。
比如:如果兩個不相干的類用引用了相同的一段功能邏輯,這時候使用繼承就無法解決這個問題,這時候就可以將這段功能邏輯定義到Utils類中,從中我們也可以看出只包含靜態(tài)方法不包含任何屬性的Utils類是面向過程編程風格,同時這里也要說明一點在面向?qū)ο缶幊踢^程中并不是要杜絕面向過程編程,如果能解決我們的實際編碼問題就可以直接使用的,使用他們的標準就是:如果我們常用的面向?qū)ο?大特性無法很好的解決編程過程中遇到的問題,如不相干類引用相同代碼或者使用共享變量等場景,就可以直接使用面向過程進行編程。
-
基于貧血模型(MVC)的開發(fā)模式
MVC這種數(shù)據(jù)和方法分類的開發(fā)模式就是面向過程編程風格,但是因為MVC開發(fā)模式對應新手開發(fā)人員具有上手快,邏輯清晰等特點,所以得以大量使用。
面向?qū)ο缶幊虨槭裁慈菀讓懗雒嫦蜻^程的代碼,包含了2點原因?
- 面向過程編程更符合人們流程化的思維方式,而面向?qū)ο缶幊淌且环N自下而上的思考方式,它是將任務拆分為一個個小的模塊(類),設計類之間的最后按照流程將類組裝起來完成任務。
- 面向?qū)ο缶幊瘫让嫦蜻^程編程更難一些,面向?qū)ο缶幊绦枰紤]如何設置合適的屬性和方法到類中,類之間的關系、交互如何設計,對開發(fā)人員來說需要一定的設計經(jīng)驗和技巧。
總結
無論是面向?qū)ο缶幊踢€是面向過程編程,我們的目的都是寫出易維護、易擴展、易讀和易復用的高質(zhì)量代碼,只要在開發(fā)過程避免面向過程編程的弊端,在掌控范圍內(nèi)使用,大可不用擔心在面向?qū)ο缶幊讨袑懗雒嫦蜻^程編程的代碼。