面向对象编程(Object Oriented Programming)概念总结及延伸(一)
1.介紹
??? 筆者的夢想是成為一個架構師,但是要成為一個合格的架構師是相當不易的,它既需要豐富的項目經驗也需要不斷地吸取新的知識,而且在這過程中我們也要不斷鞏固基礎知識。我也注意到了,現在主流的文章大都集中到了新技術新的框架的學習,大家對于最新的技術都懷有無比好奇的學習態度,這點是好的,可是只是一味站在高層學習而忽略了最本質的知識,這是不好的,所以筆者在吸取了很多教訓之后決定寫此篇文章總結自己對面向對象知識的學習。
??? 另外,需要提出的一點是,現在的開發大多基于框架或者現有類庫,因為開發人員要在很短的時間內完成開發任務,而且對于開發人員的培訓來說,課題也主要集中在了框架的學習上而忽略了基礎,我覺得這點不是很好,尤其是對想成為出色架構師的人而言。而如果當他們過渡到了軟件架構師的職位后,雖然職稱變了,以前遺留下來對于基礎知識以及架構知識的真空將成為架構高質量軟件的瓶頸。
??? 筆者本人是也無例外的成為主流趨勢下的受害者,荒廢了多年的基礎,今天要痛定思過總結面向對象的基礎知識,希望大家能幫助我完善,在這先謝謝大家了。
2.背景
??? 我們大家或多或少都應該有這么個經驗,作為新手時我們常常掙扎于理解一個新概念的準確定義,而對于有相關經驗的人他們則能夠很好地了解這些概念的意思,它的用途是什么。作為曾經不明白它意義的人之一,曾經的煎熬歷歷在目,其中的痛苦真是不言而喻。上面的道理到了軟件架構也無一例外的相似,例如:當你作為架構師開始設計自己第一個系統的時候,各方面的盲點一下子涌現了出來,這其中的痛苦真的令人很沮喪,你將應用所有你學過的知識去盡力完善設計,例如:以前的經驗告訴你每個類都要為其定義接口??傊?#xff0c;這只能是一個痛苦的過程。還有可能有人會嘲笑你設計的系統是錯誤的,然后你根據建議又進入了再學習的過程。在這過程中你思考了很多讀了很多資料,在不斷的挫折中為以前基礎的荒廢而還債。我希望本文能作為一個啟發式的文章,讓大家加深對基礎的學習,為以后的工作開個好頭。
3.主要內容
3.1 什么是軟件架構
????? 軟件架構可以被定義為以下準則:
??? (1)將問題和系統劃分為相互獨立的不同部分
??? (2)創建上述獨立部分之間的接口的技術
??? (3)管理全局的結構和流程的技術
??? (4)為系統和運行環境定義接口的技術
??? (5)能合理的使用開發和產品發布的工具、技術和方法
3.2 為什么架構這么重要?
??????? 軟件架構的主要目的是為系統和環境定義非功能需求。詳細設計是在系統功能按照架構準則劃分后才開始的。架構很重要,因為好的架構具備以下特點:
??? (1)控制復雜度
??? (2)強調使用最佳實踐
??? (3)要求系統的一致性和統一性
??? (4)為項目增加可預見性
??? (5)強調重用性
3.3 什么是面向對象編程(OOP)?
??????? OOP是一個設計哲學。它代表面向對象編程(Object Oriented Programming)。OOP使用與過程編程語言(C語言、Pascal等)不同類型的編程語言。OOP中的單位是對象(Object),通過使用面向對象的編程理念我們獲得了可重用性。
??????? 為了清晰地了解面向對象的概念,讓我們舉個簡單的例子把,例如你的手,手就是一個對象。你擁有兩中類型的手:左手和右手,它們的主要功能是由從你肩部的電信號進行管理和控制的,在這里肩部就是一個接口,身體通過這個接口和你的手進行交互。手就是一個類,通過輕微改動類中的屬性(左和右)就可以達到了手這個類的重用。
3.4 什么是對象(Object)?
??????? 一個對象可以被認為是一個事物,它可以展開一些列相關的活動。對象可以展開的活動定義了對象的行為。例如:手可以抓東西,學生可以給出自己的姓名和年齡。
?????? 在純面向對象中,一個對象被定義為一個類的實例。
3.5 什么是類(Class)?
??????? 一個類可以簡單的代表一種類型的對象。它是一個描述對象細節的藍本/模板,而對象是創建類的藍本/模板。類包含三個部分:類名、屬性和操作,如下圖所示:
圖1:類的組成
??????? 類在代碼中的編寫可以是這樣:
??????? public class Student
??????? {
??????????? //屬性和操作
??????? }
??????? 在下面給出的代碼中,我們可以說對象oStudent是由類Student創建的。
??????? Student oStudent = new Student();
??????? 在現實世界中,你會發現很多單獨的對象其實都是一類的。例如:世界上有很多的自行車,但它們都是同樣的制造和模型。每個自行車都是由同一個藍本創建的。在面向對向中,我們認為自行車是自行車類的實例。
??????? 在軟件世界中,雖然你可能沒有意識到,但是你已經在使用類了。例如,TextBox控件就是產生于TextBox這個類,它定義了外觀和功能。每次你通過VS將TextBox拖拽到設計器中你就已經在創建一個TextBox的實例了。
3.6 怎樣識別和設計類?
??????? 這是一門藝術。每個設計師都用不同的技術識別類。然而通過面向對象設計原則,有5個原則應該在設計一個類的過程中參考:
?????? (1)SRP-The Single Responsibility Principle(單獨職責原則)-
???????????? 一個類應該有且只有一個理由去改變。
?????? (2)OCP-The Open Closed Principle(開閉原則)-
???????????? 一個類應該可以在不修改的前提下擴展類的行為。
??????? (3)LSP-The LisKov Substitutable Principle(LisKov可替換原則)-???
??????????? 子類型必須能夠替換掉它們的基類型,即子類需要具備父類所有的屬性和行為??
??????? (4)DIP-The Dependency Inversion Principle-
??????????? 應該依賴與抽象而不是具體。
??????? (5)ISP-The Interface Segregation Principle-
??????????? 為客戶端定義合適粒度的接口
??????? 同時,為了正確地識別出類,你需要將系統功能分解為一個樹狀,對于這棵樹,你需要識別出達到不可再分的葉子級別功能,然后你可以將各個功能進行分組,分組后就形成了類,記住,類必須將包含地是相同類型的功能和操作。然而一個定義良好的類必須是個有意義的功能集合俄日全額應該指出可重用性,尤其是對系統要求可維護性和可擴展性很高的情況下。
??????? 在軟件世界中,有個概念叫做分治(dividing and conquering)經常被推薦,如果你在初始分析一個系統,你將發現很難去組織,所以最好的方式是首先將系統進行模塊化劃分,然后對每個模塊單獨進行深層分析,進而識別出類,這就是分治的核心思想。
??????? 一個軟件系統可能由很多類組成。但對于任何情形,對于這些類都應該進行良好的組織。設想一下一個很大的機構,它們的員工有上千人(在這里我們假設一個員工就是一個類),為了有效地管理勞動力,你需要指定合理的管理策略。對于軟件,管理策略也是必須的,為了管理軟件系統的類,降低復雜性,軟件設計者將這些策略分為以下四種:封裝(Encapsulation)、抽象(Abstraction)、繼承(Inheritance)和多態(Polymorphism),這四個概念是面向對象編程的主要準則。
?? 3.7 什么是封裝(或者信息隱藏)?
??????? 封裝的含義是是隱藏對象的屬性和實現細節,僅對外公開接口,控制在程序中屬性的讀和修改的訪問級別。對于一個封裝的程序對象而言,它包含了實現自身功能的所有資源(數據和方法)。在OOP中,類通過暴露公有(public)方法或者屬性實現封裝的,這個類就像一個容器或者膠囊,它封裝了方法和屬性的細節,外部只用知道方法和屬性的接口即可,通過封裝我們可以對類內部的實現細節進行修改而會影像整個系統??偠灾?#xff0c;封裝就是隱藏了怎么做,調用者只要知道它能做什么就行。
圖2 從類外部看封裝
?
??????? 為了可以模塊化/定義一個類的功能,這個類可以使用其它的類暴露的方法和屬性,調用的方式可以有很多種形式,在面向對象編程中,有一些技術對于類之間互相連接,它們的名字是:關聯(Association)、聚合(Aggregation)和組合(Composition)。
??????? 封裝還有很多其它用途,例如我們經常使用的接口,接口可以用來隱藏一個類的實現信息。其實這也是種封裝,如下所示:
??????? IStudent oStudent = new LocalStudent();
??????? IStudent oStudent = new ForeignStudent();
??????? 根據上邊的例子(我們假設LoaclStudent和ForeignStudent實現了IStudent這個接口),我們可以看到接口隱藏了它們的實現細節。
3.8 什么是關聯(Association)?
??????? 關聯對于兩個類而言是一種“a”的關系,簡單說,當一個對象通過對另一個對象的引用去使用另一個對象的服務或者操作時,兩個對象就互相關聯了。關聯是兩個類關系中很普遍的定義,聚合和組合相對來說比較特殊。
?????? public class StudentRegisterar
?????? {
????????????? public StudentRegisterar()
????????????? {
????????????????????? new RecordManager().Initialize();
????????????? }
?????? }
??????? 如上邊的例子,我們可以說類StudentRegisterar和類RecordManager互相關聯,也可以說有一個從StudentRegisterar到RecordManager的方向關聯以及StudentRegisterar使用(“use”)了RecordManager。既然一個方向已經顯式地指定了,在上例中StudentRegisterar是控制類。
圖3: 關聯
??????? 對于初學者而言,關聯是一個容易混淆的概念。造成這種混淆的主要原因是另兩個OOP的概念,它們是組合和聚合。當每個人都懂得了關聯的概念后,但在學習了聚合和組合后就變得混亂了。聚合和組合不能分開進行理解。如果你明白了聚合的概念,那它將會損壞你對關聯的概念,如果你理解了組合的概念,很可能它會破壞你對聚合的理解,所以這三者要一起來學習和理解,通過對比找出其中的異同。所以下面讓我們來了解以下我來了解下這三者之間的區別把。
3.9 關聯、聚合和組合三者之間的區別
??????? 關聯是兩個類之間的一個“use”的關系,一個類使用了另一個類的方法。聚合是一種特殊的關聯,對于兩個類,它們是“has a”的關系。當類的一個對象擁有(has a)另一個對象,也就是一個對象成為另外一個對象的組成部分時,我們說它們之間有種聚合關系,與關聯不同的是,聚合總是強調方向性。如下面的代碼和UML圖所示:
?????? public class University
?????? {
?????????????? //一個大學總會有個法律顧問
?????????????? private Chancellor universityChancellor = new Chancellor();
?????? }
圖4: 聚合
??????? 在上面的例子中我們可以說University聚合了Chancellor,或者說University有(has a)Chancellor。但是如果沒有法律顧問(Chancellor)大學也能存在。但是一個大學如果沒有院系(Faculties)就不可能存在,可以說University的生命周期依附于Faculty的聲明周期。如果Faculty調用了dispose方法那么University就不能存在了。對于這種情形我們可以說Univesity和Faculty是一中組合的關系。所以組合可以說是一種特殊形式的聚合。
圖5: 組合
?
?????? 我們再來看看另一個例子,.NET和Java中其實就是使用了組合關系定義集合的,而且組合還被用到了很多別的方面中,只是大多數人忽略了生命周期這個概念,生命周期對于組合的兩個對象而言是互相綁定的,它們之間互相依賴。所以如果你想將兩個對象綁定為組合關系,那么最好的方式就是你直接定義被組合的類為另一個類的內部類,訪問級別設為私有(private)或者保護(protected)。
????? 所以簡言之,我們可以說聚合是一種特殊的關聯,而組合是一種特殊的聚合,而且關聯->聚合->組合。
???? 圖6:關聯、聚合以及組合之間的關系
???? 由于精力有限,今天就寫到這里了,因為內容比較多所以難免存在腦子混亂和打字錯誤的可能,希望大家能幫助我修正,OOP的其它內容將在下篇文章中繼續總結,謝謝。
轉載于:https://www.cnblogs.com/talentbuilder/archive/2010/04/27/1722223.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的面向对象编程(Object Oriented Programming)概念总结及延伸(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apple 的CEO 吹响了战斗的号角啦
- 下一篇: Memory Ordering