閱讀目錄:程序員
最近對軟件開發有了一個新的認識,這個認識源自連續看了兩本Craig larman大師的書籍《UML與模式應用》、《精益與敏捷開發大型應用實戰》和公司目前的項目狀況這兩件事情一塊兒碰撞致使的感悟。數據庫
先說下前者,爲何會想到看Craig larman大師的書籍。其實我收藏的書籍已經上千本,在各個電商平臺上都有賬號,目的只有一個就是收藏好的書籍。家裏也堆了不少,沒事瀏覽新書是我如今最大的樂趣。我相信有這種感受和愛好的不止我一我的,家裏堆上幾十本書的在IT行業算是很正常的。編程
書多了有時候不知道要看些什麼也很正常,個人原則就是隨時調整,看目前所面臨的困惑。根據我以往的經驗總結,在實際問題面前尋找答案最容易讓你有新的感悟和提高。我相信書中自有黃金屋、書中自有顏如玉,要在對的時間看對的書,說白了就是在有困惑的時候就去尋找給你答案的這方面書籍。爲何要看Craig larman大師的書,是由於最近的工做內容有不少本身搞不懂的地方,但願能經過大師的指點有所感悟,果真受益不淺。設計模式
再說下後者,最近一直在和這幾個事情打交道:遺留代碼、技術債務、項目管理、項目質量、開發進度、快速開發、重構、單元測試、敏捷開發、Scrum、XP,你可能會有點疑惑,有些東西是重複的,好比項目管理中包含了項目質量、開發進度,再好比敏捷開發與Scrum和XP,彷佛我在把一個大的概念拆解成多個小重複的概念。我之因此這麼作,是由於我想強調這些概念的區別和真正的相互做用,從軟件工匠的藝術角度出發來真正的看待這些概念。好比說,項目質量與代碼有關係嗎,開發進度與遺留代碼有關係嗎,項目管理與技術債務有關係嗎等等,這些問題的本質是徹底不一樣的,做爲技術人員尤爲是應用開發的技術人員必定要強調概念,必定要明白不一樣的概念的本質含義,若是你不強調概念我想你的代碼是寫很差的,對業務的理解也不會深入。架構
最近我將本身的技術生涯的目標定爲「軟件工匠」,其實說實話我不在意title,我只在意本身的工做內容是什麼。軟件工匠是沒有邊界的,只要和軟件開發有關係的內容都是屬於工匠須要去專研的領域。若是工匠離開工具就喪失了工匠的真正價值所在,因此說千萬別放棄寫代碼。無論你是一名架構師仍是一名開發經理,代碼永遠是產品的最終設計,一旦你離他而去就離產品的質量愈來愈遠,後面我也會講下爲何代碼如此重要。併發
這節的標題是不受歡迎的,你們知道爲何嗎。技術人員是能明白的,有過長達5-10年的開發出生的管理者也是能明白的,惟一不明白的就是沒有太多開發經驗的管理者,或者那些不喜歡開發的管理者,那些逃避開發的管理者,由於他們離真正的產品實現太遙遠,他們離軟件開發領域真正的問題太遙遠,管理一旦忽視代碼質量問題就會慢慢找上你,你的項目日後的質量越沒法控制,度量、開發進度都會遇到瓶頸。app
說個當下的現象,我從事一線開發也有好幾年了,陸陸續續看到不少人轉做管理,可是你會發現作管理的人通常都是技術水平通常的人,或者對技術沒有太多追求的人,更誇張的是在有些小公司的管理者可能就沒寫過代碼。框架
爲何會出現這種現象,其實主要緣由有兩個,首要的就是我的的職業規劃,在就是公司的價值導向。先說價值導向,每每寫代碼的人的價值沒有項目管理的價值大,這在一些中小公司仍是很廣泛的,真正的科技型公司這類問題幾乎沒有。而職業規劃是徹底能夠接受的,畢竟每一個人的興趣和追求不一樣,這無可厚非,應該尊重每一個人的選擇。可是這裏的問題是,一旦沒有太多技術底蘊的技術人員坐上項目管理者的職位後會對技術的理解360度大轉彎。這實際上是不對的,項目的成敗不可忽視技術。編程語言
不繼續討論這個話題了,這不是本篇文章的重點,人各有志,選擇是正常的,可是要明白的是選擇的本質不是價值導向,而是興趣導向,這纔不會讓你忽視另一個角度,由於一個軟件產品的最終成功是要靠項目管理和軟件工程相共同的努力,缺一不可。工具
這裏想聊聊項目管理的三個重要的方面,質量、度量、進度。首先我不是一個專業的項目管理者,可是我是一名專業的軟件工程師,我不知道項目管理的具體內容有哪些,可是我知道項目管理的最終目標是和軟件工程的目標是一致的,都是爲了項目高質量的完成。
項目的成敗光靠項目管理是解決不了的,若是能夠就不會出現《軟件工程》、《設計本來》了。保證軟件項目的真正成功是須要軟件工程的支撐才行,而管理更加是對開發的組織、協調、溝通上的,這是兩個層面兩個角度互相做用的。項目管理中不會有設計、抽象、可維護性等這些內容。
這裏尤爲想討論的就是軟件項目的質量,如今看來衡量軟件項目的質量忽視了代碼的質量,客戶驗收、功能完成、穩定上線,沒耽誤進度,這就是完成了一個項目,咱們忽視了一個就是代碼的質量,爲何要關心代碼的質量。
度量,度量是對開發週期內全部發生的事情進行數據可視化,BUG數、發佈回退數、代碼行數(比較特殊)、需求變動數等等,還有些我不是太清楚的度量數據,總之應該會有不少。度量的目的是爲了什麼,是爲了可以在這些數據出來後改善項目的各方面質量,控制各個不穩定的方面。
開發進度,「質量」一段中我最後拋出了一個問題「爲何要關心代碼的質量」,由於他直接決定了你的項目進度,當你的代碼質量愈來愈差的時候你就失去了對項目進度的控制。你再多的度量指標都是無心義的,就算你能夠統計出BUG數上升了,可是你也控制不了BUG數降低,由於你已經偏離正常航線太遠,就算你能夠控制需求變動的速度和次數,可是你沒法控制適應變動的代碼的速度和次數。變動是沒法避免的,你的代碼沒法面對這些複雜的變化,由於你的代碼不是設計出來的而是堆出來的。最後你的項目質量也沒法很好的保證。
(圖1:項目管理與軟件工程的結合纔是完整的軟件開發)
最近在看Michael C. Feathers 大師的《修改代碼的藝術》一書,感觸頗多。裏面講到了咱們面對遺留代碼的時候,爲了增長一個新的功能要付出多少時間和精力,出現明顯的BUG機率有多高,出現隱藏的BUG機率有多高。遺留代碼直接決定了上述三個項目管理的方面。Michael C. Feathers 大師強調了不少關於我上面講到的項目管理和代碼質量之間的關係,這本書很值得看。
其實真正推進軟件開發不斷髮展的是軟件工程、開發方法論,項目管理只是輔助於軟件工程在時間和空間上有效實施。
這裏還要區別下就是項目管理和團隊管理的區別,這兩個東西是不同的。項目管理基本上不須要軟件工程的支持,可是團隊管理在某些方面是須要軟件工程的支持才能作的更好。
在《精益與敏捷開發大型應用實踐》一書中是這樣描述軟件設計和架構的:
1:「軟件架構借鑑了建築的架構,但結果證明這是個不太恰當的類比,並且給軟件開發帶來了有趣的反作用。建築是硬的,由於在這個領域,設計只在施工前進行一次,而後該建築或者設計就幾乎是永久不變的了。注意建築師和施工工人是不一樣的。可是軟件不是一座建築,軟件是軟的,並且編程也不是施工的過程,「軟件架構」只不過是一大堆比喻列表中能夠選擇的一個不太完美類比而已」。
2:「......惟一確實看起來知足工程設計條件的軟件文檔是源代碼「。
3:"我意識到圖表和文檔並非真正的設計,而源代碼纔是真正的設計。再次重申「......惟一確實看起來知足工程設計條件的軟件文檔是源代碼「。
這幾句話足以證實軟件開發是一個很是複雜的過程,是思惟密集型腦力活動,並且體如今每個編碼過程當中。在不少項目管理中都認爲軟件開發是一個很是簡單的活動,主要架構設計好編碼是比較簡單的,難道真的是這樣嗎,咱們再看看書中怎麼說的:
1:」源代碼是真正的藍圖「。
2:」真正的架構在哪裏,不管好壞、有意或偶然的?是在架構團隊維護的文檔中?仍是在上萬個文件中?顯然是後者,源代碼是真正的設計,並且它的總和反映了真實的大型設計或架構。架構就是架構,不是某人的意願「。
如今不少開發者還有一個明顯的技術理解錯誤就是」寫代碼「是比較簡單的活動。複雜的是軟件架構,只要架構設計好後寫代碼應該是程序員的事兒,這裏明顯有一個錯誤的價值觀,認爲寫代碼的人都是廉價的,不具備任何的設計和創造新。這實際上是一個很不專業的見解。真覺得一個簡單的PPT、WORD文檔中的架構圖就表示架構了。其實這個想法是很幼稚和膚淺的。用Craig larman大師的話講,在整個軟件生命週期的活動中,複雜的是編寫代碼,而代碼纔是架構,因此說架構的就是代碼。你本來理解的架構纔是真正難的地方其實也就是代碼纔是真正難的地方,不可浮於表面,這樣才能更加的接地氣才能真正的有價值。
架構師應該深刻到一線參與一些開發,這時會發現不少問題,而後將問題帶到架構的位置,用架構的視角設計方案,在親自把這個方案帶到一線落實下去,這纔是架構落地一個技術方案的正確方法。
軟件開發是一項設計活動而不是建築活動,軟件是會不斷變化的,而建築一旦敲定是不會改變的。
這節我想聊聊快速開發。在圈子裏面對快速開發的理解大部分都是和快速開發框架對應起來,以爲應該有一個框架來支持快速開發。只要有了一個框架就能夠進行快速開發。這樣的見解或想法實際上是錯誤的,對快速開發的理解太狹隘。
《設計本來》做者,計算機科學巨匠Frederick P. Brooks說過,對於軟件開發來講沒有銀彈存在,沒有所謂的可以用簡單發方法來開發複雜的系統。越複雜的系統開發起來不會簡單的,開發一個知足100我的使用的系統和開發一個知足1000我的使用的系統在複雜性上已經徹底不一樣了。量變引發質變,當業務量、訪問量、數據量等等這些軟件指標超出必定的範圍以後就和最初的設計徹底不一樣,設計思路也徹底不一樣。
回到當下。我如今常常面臨這樣的一個問題,我如今所從事的業務是比較複雜的,對系統的設計要求很高。若是用量來比喻的化,其實我如今所面對的業務量是比較大的,業務量中的業務複雜性的量其實相比於訪問量、數據量等方面的量在設計方法要難的不少。一般作設計的架構師都只會考慮併發量、訪問量而忽視業務量,好比業務的多變性、業務的擴展性,業務自己的複雜性,這尤爲考研設計能力,考驗抽象能力。這跟你用什麼編程語言用什麼數據庫是沒太大關係的。你腦殼裏運用的是OO、實體關係,這些與具體技術框架不要緊的設計思惟。
業務量對於編寫代碼要求要高不少,同比於其餘幾個量來講很難落地。訪問量、併發量能夠經過基礎架構的調整優化升級來解決,而業務量的問題域是業務邏輯,是領域模型,當前所面對的業務域,任何一個細小的業務都須要在代碼中體現。
最近陸續在作一些系統重構的工做,就在前兩天我重構了一段代碼,不是基礎性的代碼,是業務邏輯代碼。大概狀況是這樣的。
在系統中有一個重要的領域概念「重量」,這個重量的概念存在不少個業務量的質變可能性,就是說它自己不是簡單不變的,隨時存在着變化,當咱們品類擴充的時候就立馬會變化。
重量的定義是這樣的:重量=單件重×數量,看上去好像很簡單的樣子,其實不是,這裏的單件重是會變化的,有些時候是保留3位小數有些時候是保留6位小數。並且這個重量的業務邏輯是在N多個地方都須要用到的,查看代碼下來大概有幾十個地方都在重複着編寫「重量「的業務邏輯。
後來我在同事的協助下重構了這塊業務模型,爲何我這裏不用業務邏輯來形容個人重構工做,是由於我考慮業務的時候不會是過程式的,若是用」業務邏輯「來思考業務就會給人形成一個錯覺就是」過程式「的代碼結構。因此我考慮任何業務都是」模型驅動開發「方法,業務要抽象爲模型才能重用、擴展、抗變化性。這實際上是OOA/D的精髓。業務邏輯只是在模型中的一小塊一小塊的具體動做,它是在模型的範圍內使用的,而不能一上來就是業務邏輯,業務邏輯太細小不便於抽象化。
(圖2:重量、單件重模型)
我用上面的這個模型對重量業務模型進行了重構。將本來很重要的業務概念重量、單件重、不一樣類型的單件重,進行了概念顯示化,保證這些重要的領域模型不被過程式的代碼淹沒。且用兩個工廠封裝了建立重量和單件重的業務邏輯。這樣作以後咱們的模型就具備抗變化性,之後要是對Weight有任何的建立邏輯的變更咱們就能夠在WeightFactory中處理,若是有新的品類擴充進來後須要對單件重相關的處理咱們只須要擴展下ItemCategory和PieceWeightFactory兩個模型。若是你須要作爲徹底配置化,這個時候模型就更有價值。好比,咱們能夠將IitemCategory拿出去,經過品類擴展的時候自動生成相關的類型,若是你以爲這還不夠完美,咱們能夠進一步將PieceWeightFactory中有關於「根據ItemCategory建立PieceWeight(Decimal) 「,作成」Mapper模型「在進行配置化。
這裏你會發現一個很奇妙的地方就是,一旦模型化後業務的量變引發的質變能夠經過逐步重構模型、提取模型、精華模型來解決。
因此說簡單的系統結構是沒法表示複雜的業務模型的,若是能夠的話OO語言就不會發展成今天的這樣子。複雜的業務沒法經過簡單的系統結構或者說所謂的簡單的快速開發框架之類的東西能夠解決的。
不少時候咱們都在強調「多去了解業務、多去熟悉業務」,在業務驅動型公司這是必須的,公司中的任何角色的單位都須要熟悉公司的業務範圍。這沒有問題,我想說的是不一樣的角色對於業務的理解最終的業務模型是不一樣的。
無論是在傳統的軟件企業中仍是互聯網企業中,咱們要用軟件來服務於咱們或者客戶,固然這裏所說的是業務系統。業務系統的核心就是業務,系統的精神就是業務模型及模型之間的關係。
這節我想說的是,技術人員去了解業務後和產品經理去了解業務後最終的業務模型是怎樣的。技術人員與產品經理是不一樣的角色,具備不一樣的職業背景,不一樣的知識結構和專業度。如今存在一個廣泛的認識錯誤是,技術人員理解業務後與產品經理理解的業務後的最終的模型是同樣的,是怎樣的呢。是沒法抽象的業務,大概的業務,場景化的業務,沒法落地到系統中的業務。此時技術人員並無用本身的專業度來對業務進行抽象和建模,並無直接帶來真正的價值,而是在交談和理解需求的時候感受上的價值錯覺。
技術人員不可以業務技術化其實對於公司所說的「當技術人員理解業務後產生的價值是巨大的」實際上是不許確的。
產品對於業務的理解是總體上的,包括業務流程、數據流程,場景,在他們的腦子裏是真實的業務場景,是必需要還原的業務場景,不可以有任何的其餘模型在做怪。若是產品用任何的其餘知識來抽象和強制理解業務是會出現問題的。
產品對於業務的最終模型是業務流程、數據流程和一個不須要表現的場景。
(圖3:產品的業務理解最終模型—業務流程圖)
因爲數據流程圖比較簡單,當前例子中只會有「訂單」的數據實體,畫出來意義不大,我這裏就只畫一個業務流程圖來表達意思便可。
在這個程度上是沒法直接將流程圖落到系統上的,它距離真正編寫軟件還有一段過程要進化,而下面那段過程纔是技術人員理解業務後要發揮的價值和做用。
技術人員的瞭解業務要有所側重,你理解的業務和產品理解的業務是不同的,技術人員須要將業務最終技術化才行。技術人員的最終的業務模型是有正確的模式能夠參考的,就拿「建立訂單」這個流程來講,等待技術人員須要去提取和抽象的東西是比較多的也是比較複雜的,須要結合不少的知識來進行設計活動。
好比訂單,你須要結合「四色原型」模式來提取「訂單」的模型,包括「訂單的類型「、」訂單的跟蹤「,須要結合設計模式來抽象」建立訂單的邏輯「,根據」不一樣的訂單類型建立不一樣的最終訂單「。還須要進行設計模型的抽象,好比建立訂單,各個對象的交互是如何的,每一個交互的輸入和輸出是什麼。這些都須要技術人員理解了業務後應該具備的業務模型,若是須要將模型語言化就須要結合使用UML來建模。
若是技術人員理解業務後和產品經理理解業務後的結果是同樣的,那技術人員要去理解有什麼價值。技術人員理解業務後要系統化的將各個業務模型落地到具體的領域內或者說某個子系統子服務中,而後各個系統和服務是如何交互的,邏輯的歸屬究竟是哪邊的。最終你寫出來的代碼纔是知足業務的代碼模型,纔是有核心競爭力的業務系統有別於無核心競爭力的系統差距。
技術人員瞭解業務後,針對不一樣的業務場景開始建立領域模型草圖,根據領域草圖再進行設計模型草圖建立,固然這是一個敏捷的迭代的過程。
(圖4:「建立訂單」相關的領域模型)
有了領域模型以後就須要建立設計模型,也就是各個模型之間的協做關係。仍是要強調下,這是一個快速迭代的過程,且勿將其當作是瀑布的依賴過程。領域模型的精華也是沒有止境的,當後面進行設計模型的過程時會有對領域模型有補充的靈感,此時不能夠教條,要快速的精華領域模型而後再進行設計模型的過程。
(圖5:「建立訂單」相關的設計模型)
基於領域模型建立設計模型中的對象協做模型,設計模型不只僅只有協做模型一種還有其餘的。協做模型是必須的也是最重要的。有了協做模型以後咱們就能夠走查場景是否知足「建立訂單」的這麼一個業務動做。當八九不離十的時候就能夠進入到編寫代碼階段,進行一個快速的構建代碼模型,由於這個時候仍是會有問題出現,只有在代碼模型中沒有問題後纔是真的沒有了。
我這裏只是假設一個簡單的業務場景做爲示例,目的是爲了介紹技術人員區別於產品對於業務理解後的最終模型是不一樣的。技術人員必定要有完善的能將業務技術化的知識結構,這樣才能真正的將業務發揮價值。
技術債務實際上是沒法避免的,各類緣由,時間進度、需求變動、市場迫切等,都迫使研發開始堆積技術債務,代碼逐漸開始腐爛,難道咱們做爲技術人員就只有抱怨和推卸責任嗎。這裏我有一些我的見解,這些我的見解可能跟你的理解不同,你可能會說我太理想主義了,可是我想說的是:「做爲一個技術人員必定要有情懷,必定要有追求。」用我最尊敬好朋友馮老師的話說:「寫代碼必定要考究「。就算在時間比較緊的時候能夠先寫,可是要記住你的工做並無徹底完成。
我是從開發作到架構,經歷過不少項目磨練,也深知在項目時間比較緊急的時候本身是在一個什麼精神狀態下寫代碼的,本身也幹過處處複製代碼粘貼代碼的時候,加班到12點,眼睛基本上已經很難看清代碼,敲代碼的速度已經趕不上功能交付的速度。我只能說這也沒有辦法,市場決定了項目的進度。咱們能夠吐槽,可是不能抱怨,更不能消極。
其實現實狀況下咱們作開發的基本上都是在這個節奏下工做,可是我是怎麼處理這個問題的呢。首先寫好代碼是我的對技術的一個追求和職業素養的問題,若是你對代碼沒有美感你很難能編寫出好的代碼,你的代碼也會處處留有壞味道,時間長了就是腐爛的遺留代碼,嚴重的技術債務,研發成天怨聲四起,各類抱怨,吐槽,這樣下去實際上是很差的,團隊裏有追求的技術人員會流失。
實話實說,當本身今天晚上12點寫好了代碼提交了測試,可是個人工做並無完成,我一般會在早上很早就醒了,我會很早的來到公司對本身的代碼進行重構和梳理,早上是大腦特別清醒的時候,在這個時候你進行代碼的整理是很是不錯的,並且這個時候公司通常都沒什麼人,特別安靜,當你重構完代碼舒服舒服的再去整理本身天天早上來的其餘事務。
你可能會說那是你我的問題,我不必定會在次日早上能起的那麼早,就算起的來我到了公司也不會對次日的代碼進行整理,由於那已經上線了已是完成的功能,我該繼續下一個需求。
用個人價值觀來看的話,其實你的工做只完成了一半,你並無保質保量的完成工做,你的軟件交付質量在產品層面是完成了,可是你在技術層面是有殘缺的。你給軟件帶來了不少的技術債務,你給某個對象帶來了腐爛代碼的開始。
這點我如今的公司是很是不錯的,公司高層對項目的管理者首要的要求就是必須懂技術。
我一沒事就會和個人好朋友也是好同事馮老師交流技術,互相review代碼,提意見,在互相重構,彼此學習。咱們有一個共鳴,就是讓寫代碼有追求的人來把控項目是很是不錯的,能夠保質保量的完成功能,固然不是光說有寫代碼能力就OK的,須要綜合性的。其實說白了,讓一個精通技術的人在去精通業務作出來的軟件應該是不錯的。 (這裏所說的精通技術是指應用開發方面的精通,不是指技術專家、系統層的技術專家)
做爲應用開發人員,要時刻記住你所應該具備的專業的職業素養,寫代碼要講究,要記住對你來講代碼意味着什麼。
未完待續。。。。。。