如何用面向對象設計一個程序,經典推薦?
面向對象設計即 OOD(Object Oriented Design)
看了面向對象的書,但是不知道怎麼用,例如怎麼根據實際問題設計類,繼承什麼,有沒有將如何規劃類,繼承的書
謝邀!
可能是題主看的書不夠好。我是從 1998 年開始正式學習 OOA、OOD 的。在我的印象中,過去 15 年好像沒有哪一本講解 OOAD 的教學書超過了這本暢銷經典(Amazon 上的 #1 Best Seller)—— OO 與 敏捷大師 Craig Larman 的 Applying UML and Patterns(中文版《UML 和模式應用》)。這書從第 1 版,到第 2 版(基於 UP),到第 3 版(基於 Agile),可以說一直都是經典。
怎麼根據實際問題設計類,繼承什麼,有沒有將如何規劃類,繼承的書
題主的這個問題是個初學者 FAQ,OOP 、OOD 最基礎的一個問題,也正是上世紀 1990 年代軟體工程專家們討論的最熱話題之一。如何把一個系統分解為多個類,這些類之間是什麼關係(繼承、關聯、依賴等等),如何規劃?對象的職責應該如何分配?。。。當年有許多 OOD 方法論流派,後來逐漸形成一致意見,出現了許多穩定、成熟的類設計原則、模式、方法和技巧,這些在 Larman 的書里都有反映,例如其中一組最基礎的類設計、規劃原則(和模式)叫 GRASP,初學者應該先從 GRASP 原則學起。
http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/OO 大師們的讚譽
「This edition contains Larman』s usual accurate and thoughtful writing. It is a very good book made even better.」
—Alistair Cockburn, author of Writing Effective Use Cases and Surviving OO Projects「Too
few people have a knack for explaining things. Fewer still have a
handle on software analysis and design. Craig Larman has both.」—John Vlissides, author of Design Patterns and Pattern Hatching「People
often ask me which is the best book to introduce them to the world of
OO design. Ever since I came across it Applying UML and Patterns has
been my unreserved choice.」—Martin Fowler, author of UML Distilled and Refactoring「This
book makes learning UML enjoyable and pragmatic by incrementally
introducing it as an intuitive language for specifying the artifacts of
object analysis and design. It is a well written introduction to UML and
object methods by an expert practitioner.」—Cris Kobryn, Chair of the UML Revision Task Force and UML 2.0 Working Group
這書從需求(問題)分析開始,到類的設計,UML 建模,設計模式,架構設計。。。,一直到實際代碼,基礎的 OO 設計原理、原則、方法和技巧,都講解得非常清晰和細緻,非常適合初學者、業餘或專業的初中級碼農學習。
閱讀建議
如果你英語 Ok,建議直接讀第 3 版的原版或影印版。作為本土加拿大人,Larman 的英語行文淺顯易懂,簡明流暢。我感覺讀起來比 Martin Fowler 的文字更輕鬆,相當大學英語水平的讀者應該沒什麼閱讀難度。
這書應該精讀。觀念上別把面向對象想成高深的方法論,關注具體的事情,相信常識,循序漸進。很多人學OOP覺得摸不著頭腦,是因為太相信方法論,而不相信自己;總覺得應不應該如何,而忽略了可不可以如何;覺得OOP是一種定法,而忘記了自發的嘗試。嘗試才是OOP的樂趣所在。
比如OOP一個博客系統,很明顯系統里會有許多「文章」,那麼把一篇文章會有的屬性先列出來,寫一個簡單的文章類,把各個屬性的getter,setter都設置好(依賴於你用的語言),用代碼去new這個文章類,作一些簡單的操作,這離最終的設計還比較遠,但至少這樣能讓自己有一個開始,有一個迭代的基礎很重要,OOP通常不能一蹴而就。
class Article {
private title;
public function getTitle() { return this.title; }
public function setTitle(title) { this.title = title; }
...
}
myArticle = new Article();
myArticle.title = "My title";
...
在此基礎上考慮是不是「需要」構造函數,保持簡單直觀往往比方法重要。
class Article {
private title;
public function Article(title, ...) {
this.title = title;
}
}
還是以文章類為例,你發現你希望Article能保存進資料庫,你既可以在Article類里實現save()方法,也可以另外寫一個Database類,然後把article對象交給Database,或者還有別的辦法,總之方法不止一種。
class Article {
public function save() {
// save to db
}
}
myArticle = new Article()
myArticle.title = ....
myArticle.save()
class Database() {
public function saveArticle(article) {
// save article to db
}
}
db = new Database()
myArticle = new Article()
myArticle.title = ...
db.save(myArticle)
這是通常人們覺得OOP複雜,模稜兩可,不好把握的地方。很多時候是因為我們假設存在"最佳「答案,其實很多時候沒有最佳答案,此時的最佳答案,到了另一個時候,就不一定是了。在沒有經驗之前,學習OOP的好方法就是把這些可能性都實現一遍,這樣才能找到合適的設計。
然後你可能需要設計一個用戶(User)類,並且注意到用戶類也要保存到資料庫,這個時候你開始考慮各種對象和資料庫之間的關係,你可以把Database類設計得更加通用,也可能考慮把database對象放進Article和User類(mixin),從而讓這些對象獲得對資料庫的引用。
class Article {
protected db;
public function setDB(db) { this.db = db; }
}
class User {
protected db;
public function setDB(db) { this.db = db; }
}
你也許發現這樣似乎有點重複,能不能把這些共用的東西抽象成一個更通用的「資料庫對象」呢,它們不都是最終會放進資料庫的對象嗎?
class DBObject {
protected db;
public function setDB(db) { this.db = db; }
public function save() { ... }
}
class Article inherits DBObject {
}
class User inherits DBObject {
}
或者還有別的更好的辦法。我只是想告訴你OOP的思考過程,而不是要告訴你問題的最終答案。
好的OOP設計是通過對問題的逐步理解,迭代出來的。不是拿著封裝/繼承/多態/設計模式這些東西去套你的問題。
關注具體的事情,相信常識,循序漸進
Head First Object-oriented Analysis and Design (amazon.cn)
Head First Object-Oriented Analysis and Design (amazon.com)擬人啊~ ~ ~讀取器可以做成Reader,寫入器可以做成Writer,實現的時候考慮到它們有重複代碼,可以抽象出來一個父類……常駐後台的任務起名叫Worker,每個任務單元可以起名叫Task,那麼操縱任務隊列的就叫Manipulator唄~ ~ ~好歡樂有木有,其實就是這麼稀鬆平常的東西,擬人,把它們當成你的朋友,置身於系統,就好了^_^當然了,從定義上講,類的本質是……好吧,關於類的本質都可以寫一本書了,不自己實現一個編譯器就永遠會有疑問,那麼何不從最簡單的demo開始呢?
敏捷軟體開發 (豆瓣)
不要為了面向對象而面向對象。實踐出真知,主要思想是減少重複代碼,代碼容易復用,容易修改,各模塊關聯小。推薦看看《重構》這本書,比麵線對象編程什麼的書來得實際。
就那麼用著類庫,時間長了自然就會寫了,面向對象最重要的是抽象,也就是繼承,因為它寫出來的類庫容易用。不過一般情況下用不到,面向過程蠻好的,不要為了oo而oo。
推薦 effective java
首先你要有需求
推薦閱讀: