六大設計原則
先看一幅圖吧:
這幅圖清晰地表達了六大設計原則,但僅限於它們叫什麼名字而已,它們具體是什麼意思呢?下面我將從原文、譯文、理解、應用,這四個方面分別進行闡述。
1.單一職責原則(Single Responsibility Principle - SRP)
原文:There should never be more than one reason for a class to change.
譯文:永遠不應該有多於一個原因來改變某個類。
理解:對於一個類而言,應該僅有一個引起它變化的原因。說白了就是,不同的類具備不同的職責,各施其責。這就好比一個團隊,大家分工協作,互不影響,各做各的事情。
應用:當我們做系統設計時,如果發現有一個類擁有了兩種的職責,那就問自己一個問題:可以將這個類分成兩個類嗎?如果真的有必要,那就分吧。千萬不要讓一個類乾的事情太多!
複製程式碼
2.開放封閉原則(Open Closed Principle - OCP)
原文:Software entities like classes, modules and functions should be open for extension but closed for modifications.
譯文:軟體實體,如:類、模組與函式,對於擴充套件應該是開放的,但對於修改應該是封閉的。
理解:簡言之,對擴充套件開放,對修改封閉。換句話說,可以去擴充套件類,但不要去修改類。
應用:當需求有改動,要修改程式碼了,此時您要做的是,儘量用繼承或組合的方式來擴充套件類的功能,而不是直接修改類的程式碼。當然,如果能夠確保對整體架構不會產生任何影響,那麼也沒必要搞得那麼複雜了,直接改這個類吧。
複製程式碼
3.里氏替換原則(Liskov Substitution Principle - LSP)
原文:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
譯文:使用基類的指標或引用的函式,必須是在不知情的情況下,能夠使用派生類的物件。
理解:父類能夠替換子類,但子類不一定能替換父類。也就是說,在程式碼中可以將父類全部替換為子類,程式不會報錯,也不會在執行時出現任何異常,但反過來卻不一定成立。
應用:在繼承類時,務必重寫(Override)父類中所有的方法,尤其需要注意父類的 protected 方法(它們往往是讓您重寫的),子類儘量不要暴露自己的 public 方法供外界呼叫。
複製程式碼
該原則由麻省理工學院的 Barbara Liskov女士提出,她是美國第一位獲取計算機博士學位的女性,曾經也獲得過計算機圖靈獎。
4.最少知識原則(Least Knowledge Principle - LKP)
原文:Only talk to you immediate friends.
譯文:只與你最直接的朋友交流。
理解:儘量減少物件之間的互動,從而減小類之間的耦合。簡言之,一定要做到:低耦合,高內聚。
應用:在做系統設計時,不要讓一個類依賴於太多的其他類,需儘量減小依賴關係,否則,您死都不知道自己怎麼死的。
複製程式碼
該原則也稱為“迪米特法則(Law of Demeter)”,由 Ian Holland 提出。這個人不太願意和陌生人說話,只和他走得最近的朋友們交流。
5.介面隔離原則(Interface Segregation Principle - ISP)
原文:The dependency of one class to another one should depend on the smallest possible interface.
譯文:一個類與另一個類之間的依賴性,應該依賴於儘可能小的介面。
理解:不要對外暴露沒有實際意義的介面。也就是說,介面是給別人呼叫的,那就不要去為難別人了,儘可能保證介面的實用性吧。她好,我也好。
應用:當需要對外暴露介面時,需要再三斟酌,如果真的沒有必要對外提供的,就刪了吧。一旦您提供了,就意味著,您將來要多做一件事情,何苦要給自己找事做呢。
複製程式碼
6.依賴倒置原則(Dependence Inversion Principle - DIP)
原文:High level modules should not depends upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
譯文:高層模組不應該依賴於低層模組,它們應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。
理解:應該面向介面程式設計,不應該面向實現類程式設計。面向實現類程式設計,相當於就是論事,那是正向依賴(正常人思維);面向介面程式設計,相當於通過事物表象來看本質,那是反向依賴,即依賴倒置(程式設計師思維)。
應用:並不是說,所有的類都要有一個對應的介面,而是說,如果有介面,那就儘量使用介面來程式設計吧。
複製程式碼
將以上六大原則的英文首字母拼在一起就是 SOLID(穩定的),所以也稱之為 SOLID 原則。
只有滿足了這六大原則,才能設計出穩定的軟體架構!但它們畢竟只是原則,只是四人幫給我們的建議,有些時候我們還是要學會靈活應變,千萬不要生搬硬套,否則只會把簡單問題複雜化,切記!
針對上面的技術我特意整理了一下,有很多技術不是靠幾句話能講清楚,所以乾脆找朋友錄製了一些視訊,很多問題其實答案很簡單,但是背後的思考和邏輯不簡單,要做到知其然還要知其所以然。如果想學習Java工程化、高效能及分散式、深入淺出。微服務、Spring,MyBatis,Netty原始碼分析的朋友可以加我的Java進階群:680130298,群裡有阿里大牛直播講解技術,以及Java大型網際網路技術的視訊免費分享給大家。
精彩繼續
敏捷開發模式的修煉之道
曾經我們開發專案都是採用傳統的“瀑布式”流程進行開發,即需求、設計、開發、測試、上線等階段,其中每個階段都有明確的交付時間點,且每個階段都依賴於它的上個階段,一旦需求有變化,就會影響後續的每個階段,專案管理存在一定的風險。為了避免這個風險,做到更好地擁抱變化,我們嘗試使用了敏捷開發方法,最為典型的是 Scrum。我們參考Scrum 的流程結合自身的特點,總結了一套更容易落地的Scrum,後面我會跟大家講到一些相關細節。
我理解的敏捷開發實際上是一個輕量級的專案管理規範,因為我們可以將整個大的需求範圍拆分成若干迭代週期,我們為這些迭代週期設定明確的里程碑,且評估完成這些功能需要花費的成本,更重要的是,每次迭代完成以後,我們會對本次迭代進行一個回顧,取其精華,去其糟粕,不斷完善,持續改進。
敏捷開發現在已經成為了主流,傳統開發模式已經出現了明顯的缺陷,隨著網際網路的發展,軟體開發的節奏會越來越快,變化也會越來越頻繁,需要我們能夠快速地發現變化,並進行及時地調整。
敏捷開發的未來會變得更好,不僅僅在軟體開發行業,而且可能會在其它行業裡也會得到應用,因為從客戶的角度來看,他們想要的是能通過最短的時間看到自己想要的東西,很多時候不做出一點東西出來,客戶是沒有任何想法的,所以需要將事情分解成多階段,迭代完成每個階段的里程碑,讓客戶滿意,才是企業最大的收穫。
敏捷這個話題大家一直都在談論,也有很多關於敏捷的工具或方法,我個人比較傾向於 Scrum。我理解的敏捷其實是一種思想,Scrum 是對讓這個思想落地的一個參考。也就是說,我們大可不必完全拘泥於 Scrum 定義的規範,只需要參考它並結合自身的條件做適當調整即可。比如說,每日站會這個環節就非常重要,不管是放在每天上午,還是放在每天下午,總之最好要有固定的週期。此外,每次 Sprint(迭代)結束後除了有評審會以外,Scrum Master 不要忘記對本次 Sprint 做一個回顧與總結,哪些是本次迭代中做的好的地方,哪些是做的不好的,再對比上次迭代的的結論,哪些是有改進的,哪些是新的問題。
Scrum 提供了三類角色,分別是:Product Owner(一般由產品經理擔任)、Scrum Master(一般由開發經理擔任)、Scrum Team(包括開發與測試人員),其中,Scrum Master 的角色至關重要,對專案的成敗起決定性作用。
阿里巴巴也在廣泛使用 Scrum 敏捷開發模式,而且整個專案幾十人都可以用 Scrum,只是首先需要將整個團隊拆分成若干小團隊,保證每個小團隊按照 Scrum 進行操作,此外,再將每個小團隊的 Scrum Master 召集在一起,再做一輪 Scrum,這就是所謂的 Scrum of Scrum。過程稍微複雜一點,但可以將敏捷用於更大的團隊規模,並能保證敏捷的效果。
敏捷開發工具“看板”,該詞彙來自於島國,當我看到看板的英文時,我真的驚呆了,看板竟然就是 Kanban?!
我們可以結合 Scrum 與 Kanban,讓專案管理更加有效,讓資源分配更加合理,讓績效考核更加公平!
對於專案經理而言,最擔心的就是專案進度不可控,不知道每位開發人員具體的工作進度,有了 Kanban 一切都是那麼地清晰。 對於開發經理而言,最擔心的就是資源分配不合理,忙的人忙死,閒的人閒死,有了 Kanban 一切都是那麼地自然。 對於開發人員而言,最擔心的就是績效考核不公平,“憑什麼我做的比他多,拿的工資卻比他少?不公平啊!”有了 Kanban 一切都是那麼地公平。 可見,專案經理、開發經理、開發人員擁有了 Kanban,也就擁有了和諧與快樂!
那麼 Kanban 到底是什麼呢?我們先來看看這張表格吧:
下面我們來理解一下這個表格吧!
這個表格有 5 列:Backlog(原始需求)、Selected(被選中的需求)、Develop(開發階段)、Deploy(部署階段)、Live(上線階段) 其中 Develop 階段包括 2 個子階段:Ongoing(進行中)、Done(已完成) 包括 3 中角色:產品經理(紅色小人)、開發人員(藍色小人)、部署人員(綠色小人),其實還有專案經理,只是他/她貫穿於始終,所有就沒有畫出來了。 在 Backlog 中放置了許多小卡片,它們在 Kanban 中被稱為 WIP(Work In Process,在製品)。對於產品經理而言,WIP 是需求,而對於開發人員與部署人員而言,WIP 卻是任務。
實際這些 WIP 卡片上都帶有一些文字描述,包括:標題、描述、優先順序等資訊。
需要注意的是,Selected、Develop、Deploy 下方有一個數字,該數字表示此階段中最多可以放置的 WIP 數量。例如,在 Selected 中最多隻能放 2 個 WIP;在 Develop 中(包括它的子階段)最多隻能放置 2 個 WIP。這裡的數字只是一個示例,具體多少可根據團隊實際情況而定。有一個經驗公式可以參考“WIP 上限 = 團隊規模 * 2 - 1”,減 1 表示大家需要協作,例如:4 人的團隊,WIP 上限是 7。
也許有人會提出,為什麼沒有 Test 階段?—— 這個可以有,這裡只是一個示例而已,你不妨自行加上去。
對於多個專案而言,可以在這張表格中新增更多的泳道(行),每一行相當於一個專案,所有的專案進度清晰明瞭。
好!繼續我們的 Kanban,有意思的事情即將發生!
產品經理挑選了 2 個 WIP 到 Selected 中,此時,由開發經理決定該任務的技術難度,並由專案經理將任務分配到指定的開發人員,也可將同一個任務分配給兩個人,讓他們去結對程式設計。
開發人員(架構師與程式設計師)可對 Selected 中的需求進行工作量評估,可採用投票的方式進行,最終給出一個合理的評估值,整個估算過程,專案經理無需參與,主要是開發人員共同完成。
開發經理可以對任務設定一個“分值”,這個分值可直接影響到後續的績效考核,所以對大家來說,這個分值是公開可見的,誰做的多,誰做得少,一目了 然。當然,開發人員也可以主動承擔具有更具挑戰的任務(為了鍛鍊自己,也為了多拿點錢),但任務分配的決定權始終在專案經理手中。
現在假設 A、B 兩個任務已經分別被不同的開發人員處理了,那麼這些任務就應該移動到 Ongoing 中,同時,產品經理可以從 Backlog 中挑選出 2 個優先順序較高的需求到 Selected 中。這樣就保證 Selected 與 Develop 都達到了 WIP 的上限。
有人已經把 A 做完了,那麼 A 就可以移動到 Done 中了。隨後,部署人員就可以開始幹活了。
部署人員就可以將 A 從 Done 中移動到 Deploy 中,表示部署人員正在做這件事情。同時,做完了 A 任務的開發人員可以再做其它新任務,只需從 Selected 中移動到 Ongoing 中,移動這件事情不是開發人員隨意操作的,而是有專案經理負責的。產品經理發現 Selected 中只有一個 D,就可以考慮放入一些新的需求了。
此時,部署人員遇到了問題,發現 A 部署的時候總是報錯,跑不起來了。同時,其他開發人員也完成了 B 任務。
完成了 B 任務的開發人員本來是可以做新需求的,但專案經理發現 Develop 中只能放 2 個任務,所以肯定是後面的階段出現了問題,導致整個流程受阻了。專案經理可以靈活排程人力資源,集中火力解決現在所遇到的問題。
所以專案經理不得不放棄新的任務,去讓開發人員去幫助部署人員來解決問題。此時,其他的開發人員還在進行 C 任務。
部署的問題還沒來得及解決,此時 C 任務也完成了,同時,產品經理也放入了新的 K 需求,確保 Selected 這個水池是裝滿水的。
整個部署問題看起來比較搞人,所有的開發人員全都上陣了,集中更多人的智慧,解決這個棘手的問題。此時,產品經理不能放入更多的需求,由於此時 Selected 已經滿額了。其實,開發人員面對太多的需求時,往往都會倍感壓力,身心憔悴。
看來這個部署問題,確實夠折騰的,連產品經理都過來了湊熱鬧了。但他或許不懂技術,但多個人多個頭腦吧,正所謂“當局者迷,旁觀者清”,最終經過大家的努力,肯定會攻克這座碉堡!
幾天之後,Kanban 流程依舊是穩定的,大家分工協作,人力資源合理利用。大家是一個團隊,目標就是把專案做好,不會因為自己的事情做完了就閒置了。
我們不妨將這張表格貼到牆上去吧!讓每個員工都可以看到,讓過路的老闆們也可以看到我們的辛苦努力,這確實是一種非常好的專案管理方法!
在這裡給大家提供一個學習交流的平臺,java架構師群:680130298
-
具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加群。
-
在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加群。
-
如果沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的可以加群。
最後給大家提出以下 10 點建議及其目標:
-
Sprint 第一天,需要將目標定義清楚,並讓團隊所有人都知道「確保建立一致的目標並使之明確」;
-
若出現需求變更,則優先排到下次迭代,特殊情況需特殊處理「確保本次迭代可以按時完工」;
-
Scrum Master 將迭代中的需求分解為任務,每個任務只能有一個任務負責人,且不超過一個人天「確保每日任務可評估」;
-
讓 Product Owner 直接與相關開發人員確定需求,Scrum Master 需一同參與「確保需求與實現不會發生偏差」;
-
每日定時站會,時長不超過 15 分鐘,規模不要太大「確保任務完成情況與計劃保持一致」;
-
每日進行一次程式碼評審,由 Scrum Master 負責,並在次日將評審結果通知給相關開發人員「確保程式碼質量不要下降」;
-
各個團隊的 Scrum Master 保持每日溝通一次,時間不要超過 15 分鐘「確保專案管理不會出現風險」;
-
每次迭代結束,讓大家稍微放鬆一下,可提供一些團隊活動,比如聚餐「確保團隊能夠更加凝聚」;
-
Scrum Master 需要給團隊一些承諾,比如專案獎金或特殊福利等「確保團隊更加有激情」;
-
對於情緒異常的員工,Scrum Master 需及時與其溝通「確保不要讓一個人的情緒影響整個團隊」;
此外,作為專案管理者,需要不斷在團隊中加強以下 6 點文化:
-
方向一致
-
當面溝通
-
全情投入
-
充分信任
-
說到做到