1. 程式人生 > >資深架構師的經驗分享——軟件項目開發和決策

資深架構師的經驗分享——軟件項目開發和決策

oracl 標準庫 可能性 scrip 而不是 轉換 linu 質量保證 strong

這篇文章是關於什麽的

參與項目決策的人必須意識到他們的決定對項目的成功和成本以及時間和金錢的影響。

對於我20多年的軟件開發經驗和10多年的咨詢工作,我作為架構師或開發人員參與了許多項目 - 其中大多數成功,有些失敗,但每個項目(無論成功與否)都涉及好的和不好的決策由各種人制作。

本文的目的是通過提倡根據我的經驗做出的決定以及避免錯誤的決策來為項目成功奠定基礎。

總的來說,我擁有C ++,Java,C#和JavaScript的經驗,但在過去的10年中,我一直主要致力於C#桌面應用程序。盡管如此,這裏提出的許多想法都具有一般性。當我討論一個C#桌面應用程序時,我明確地陳述它。

軟件開發始終存在一個“政治組件” - 本文不涉及這一點。本文的目的是提供建議,以最大限度地提高客戶滿意度,同時最大限度地減少支出。

項目開發主要指南

在這裏,我介紹了軟件開發的兩個主要準則,這將在文章中進一步詳細描述。

  1. 在軟件開發主題上有很多書籍,文章和更多的廣告垃圾。用一粒鹽吧!如果你讀的東西與常識沖突 - 選擇常識。

  2. 在公司,項目或個人層面,需求的傳播(特別是API需求)應該從使用它的人(客戶)流向構建它的人,而不是相反。通過客戶端,我也指同一項目中使用其他人構建的軟件的開發人員。這個非常重要的規則常常被忽視,不利於項目的成功。

在項目的開始

在一個項目的開始階段就要做出一些重要的決定。理論上,在項目開始時做出的錯誤決策可以稍後糾正。然而,錯誤的決定浪費的金錢或時間越多,後來糾正的可能性越小,因為糾正它們會引發能力問題。

選擇一種語言

技術分享圖片

對於一門語言,我強烈建議不要使用C ++(除非你正在構建一些非常高性能的算法,因為它的編譯時間很慢,因此一秒鐘的分裂至關重要)。每個軟件開發(如果正確完成)都涉及很多原型設計,並重新啟動應用程序或為應用程序運行測試。代碼更改後的每次新運行都涉及編譯。C ++模板的構建方式是在編譯時必須生成代碼,這樣C ++通常編譯起來非常慢。編譯速度緩慢將導致原型設計速度緩慢,開發速度相應緩慢。沒有模板,C ++沒有現代強類型語言那麽強大。

而且,Java和C#擁有許多內置於該語言的標準庫,而C ++則依賴於第三方庫。

最佳團隊規模

技術分享圖片

在我的經驗中,較小的團隊可以更快地生成更好的軟 例如,對於桌面三層項目,我會推薦一個3人團隊 - 每個層級一個人+一個建築師+ 1-3個裁員。

我最成功的項目正是由3-7名成員組成的團隊。我參與過的最不成功的項目之一是擁有20多名成員的團隊,幾年內無法實現幾個月內小型項目將實現的目標。

Scrum或不Scrum

技術分享圖片

毫無疑問 - 對Scrum來說!敏捷/ Scrum可能並不完美,但它比替代品更好。然而,Scrum的某些方面並不有效(我認為它們不應該成為過程的一部分,盡管大多數敏捷教科書都會提到它們)。以下是scrum的正面和負面特征列表。我的建議是:避免使用負面特征。

Scrum的積極

  1. 通常,在項目開始時,客戶本身可能不清楚他們需要什麽。它需要很多叠代(包括客戶和開發人員的錯誤)讓客戶弄清楚需要構建什麽,以及開發人員如何構建它。Scrum的叠代方法最適合這種範式。

  2. 在scrum之下,開發人員可以估計自己需要多長時間才能實現某個功能 - 他們通常可以做得比管理人員好得多。

  3. 每日更新對經理和開發人員都有益。雙方都可以更好地了解項目的位置。此外,對於開發者來說,這是一個與他人分享他們一直在努力工作的機會,以便了解他人正在做什麽,並且一般來說,在編程時可以鍛煉大腦的非編程部分部分休息一下。

  4. Scrum會議結束後,包括演示和計劃在內,也會因日常會議的原因而受益,但規模較大。

Scrum的負面影響

  1. 一些Scrum版本倡導只跟蹤整個團隊的表現 - 不考慮個人開發者的貢獻。雖然團隊績效非常重要,但認識個人努力仍然很重要。

  2. 在Scrum結束時召開了會議,人們捶胸說出了什麽問題 - 越多越好。我從來沒有看到從他們身上出現任何好東西。發生問題時,應由開發人員解決。更嚴重的問題應該升級到建築師/經理,有時候應該改變項目程序。

對等編程

技術分享圖片

除非是短期的,並且由兩個願意合作夥伴完全自願地分享知識,否則永遠不會看到任何好的同伴節目。

我練習非常積極,快速,以結果為導向的編程 - 觀看別人的節目讓我想睡覺。我認識的每個人都被迫做同儕編程,分享我對它的看法。

選擇軟件包和第三方組件

你應該非常小心選擇3 次黨庫-你應該懷疑華而不實的演示和廣告。選擇一個3 次方包(無論是開源還是需要付出的東西),只有當以下條件之一是true

  1. 這是一個眾所周知的產品 - 如MS Visual Studio,Oracle DB,MS SQL Server,Telerik或DevExpress控件 - 擁有數千種證詞

  2. 您的開發人員將直接使用該軟件,並在合理的時間內對該軟件進行試驗,至少兩周,並且使用起來非常舒適。

請記住,您為軟件包支付的金額越多 - 之後將更換或更換副本越困難,因為您花錢的人會希望確保這筆錢不會被浪費。

請記住,偉大的公司仍然可以有糟糕的產品。我多年前就有一個團隊對Oracle的Stellent軟件產生了負面影響 - 他們花費了大約25萬美元!對於甲骨文而言,他們當時剛剛購買了Stellent,因此它完全是在Oracle之外開發的。

此外,還記得那花了一個月研究3 個在一開始方組件可以從字面上拯救你年後。

第三方組成部分的一些具體建議

本部分針對MS桌面系統。

UI控件的包

對於WPF前端,我推薦以下軟件包:

  1. Telerik - 用WPF概念構建而成,易於修改和學習。

  2. DevExpress - 不需要 WPF(在我看來),所以定制起來不那麽容易,但仍然靈活而且速度很快。它具有Telerik沒有的一些控件,包括允許用戶在運行時組裝WPF視圖和地理地圖控件的設計器控件。

我對Xceed了解不多,但從我聽到的情況來看,它的使用也相當不錯。

我會警告反對Syncfusion - 至少幾年前,它建立與WPF意識形態相反。

我會推薦反對Infragistics - 它具有最開箱即用的功能,但根據我的經驗,這很難定制,而在WPF中,定制是遊戲的名稱!

所有上述WPF軟件包在制圖時都會遇到性能問題。我與之合作的WPF Chart軟件包,我強烈建議使用SciChart。

無論您選擇何種軟件包 - 選擇包含下載源代碼權限的許可證。每當我使用Telerik或DevExpress時,我都必須研究他們的代碼,以便能夠產生我的客戶所期望的效果。

IoC容器

大多數體面的規模項目都應該包含控制的倒置,以便為項目構建擴展點或便於交換實際測試實現的實現(例如,當涉及到對後端測試前端功能時)。

大多數情況下,我使用的MEF2有點復雜,但總是適合項目的目的。

我聽到很多Ninject的正面評論(盡管我自己從未使用過)。

我正在開發Roxy IoC容器。它仍在進行中,特別是在IoC方面,所以我現在不能推薦它。希望我能在幾周內推薦它。

測試框架

不管怎樣,Xunit是我所知道的最好的測試框架,我極力推薦它。這是免費的。它允許使用各種基於屬性的輸入來運行相同的測試。在其他框架中,您必須為每個輸入組合編寫單獨的代碼。

中間層

在MS宇宙中,我會建議使用MVC控制器或WebApi或WCF構建自定義中間層。我也喜歡在中間層使用ADO Entity Framework。

WCF比ASP中間層解決方案更復雜,更強大。通常,ASP中間層對於此目的來說已經足夠了,但對於更復雜的需求,比如使用TCP連接而不是HTTP,WCF很棒。

後端

對於體面大小的項目,我建議使用Oracle或MS SQL Server。根據我的經驗,最多不使用SQL數據庫作為緩存機制與SQL數據庫一起使用,或者用於某些特殊操作,例如全局搜索。

項目工具

我使用了許多工具,下面是我推薦的工具:

對於源代碼控制,我推薦Git和Subversion; 都工作得很好,都是免費的 - 我的首選是Git。

作為需求/錯誤跟蹤系統,我推薦Atlassian Jira或Rally。兩者都是高度可配置,經過充分測試的解決方案。

為了構建,發布和持續集成,我推薦Atlassian Bamboo。

請註意,當用戶數少於10時,Atlassian軟件非常便宜。對於這樣的團隊,每個產品的平均費率為每月10美元。

進步vs保守派

團隊中總有人渴望並願意學習新軟件和新軟件包(我就是其中之一),以及那些想要堅持熟悉的老軟件和舊軟件包的人。

以下是這些方法合理的一些例子。

進步是正確的

  1. 很久以前,由於縮短了編譯時間和原生包,從C ++切換到Java極大地提高了項目的生產力。

  2. 切換到WPF和C#絕對是一個偉大的決定 - WPF是最好的基於Windows的桌面開發包,而C#現在比Java更強大,並且不斷改進。

  3. 人們采用反應式擴展的速度很慢,但它絕對是一個很好的軟件包,可以用來構建過去非常復雜的事情。

  4. Roslyn是一款出色的C#編譯器,我相信它最終將使人們能夠實現自己的語言特性,同時提供完整的IDE支持。

當保守派是對的

在過去的10年中,微軟發布了許多失敗的軟件包。(這教會我小心)。

  1. 我對Silverlight仍然非常痛苦。我認為這是一個偉大的web開發包。我敢打賭Silverlight(盡管我明白它是微軟的一種慈善行為,因為它破壞了自己的平臺),我輸了。

  2. Windows RT,曾經被MS積極推廣的多個Windows Phone平臺失敗。(我已經更聰明了,從一開始我就感覺不太好)

關於預測包裹何時失敗或成功的一些想法

恐怕以100%確定性來預測幾乎是不可能的。

WPF是一個很好的包,我從第一眼就愛上了它的概念(之前我有過很多類似的想法)。

Silverlight也是由MS完全維護的一個很好的軟件包,當MS決定他們不再需要時,它基本上已經死亡。

Windows RT是一個翻版,我覺得它從一開始就會成為一個翻版,因為他們偏離了.NET並試圖進入本地。

我猜的經驗法則是:

  1. 當MS發布一款優秀的產品並在其背後放置一些肌肉時 - 產品就會蓬勃發展。

  2. 當MS發布一款優秀的產品並停產時 - 產品就會死亡。

  3. 即使MS肌肉也無法挽救糟糕的產品。

我想在本小節中對有關新的MS軟件包的一些預測加以限制。

基於我掌握的有限信息,我相信Xamarin擁有光榮的未來 - 它有望成為智能手機和平板電腦編程的主要手段之一。

恐怕UWP不會飛,因為它只適用於Windows 10和Windows 10產品。您將無法在Windows 8或Windows 7上運行它,更不用說Linux或Mac。為什麽使用它,如果它只是WPF和WPF在任何Windows平臺上運行的蒼白陰影?

我以前錯了,我可能又錯了 - 時間會顯示。

在項目開始前或開始時進行原型設計

盡管Agile具有叠代性,事實上客戶可能只是對最終產品應該在一開始就應該有一個模糊的概念,但項目設計師在開始時至少想出了一個小原型是一個好習慣項目。

這樣的原型應該結合一些UI,中間層和數據庫功能以及基本的測試項目。應用程序的所有部分應該可操作並相互通信,並且應該運行測試。

根據我的經驗,我建議在原型上花費2周到1個月的時間。只有在建築師要求的情況下,建築師才能在別人的幫助下親自完成。

該項目的其余部分將涉及擴大原始原型。

除了作為參考的初始參考點之外,這樣的原型還可以讓管理人員和團隊確信他們做出的決定以及他們使用的第三方組件將實際達到最終目標。

3層架構

這是標準的3層體系結構模式:

技術分享圖片

在圖中 - 雙面黑色箭頭表示從UI客戶端到中間層以及從中間層到數據庫的請求 - 響應連接。

單側紅色箭頭表示從實時饋送到中間層和客戶(訂閱它)的“熱”(實時)連接。此外,它還顯示一旦收到實時數據,它可能會記錄到數據庫中(從中間層到數據庫的紅色箭頭)。

中間層可以有高速緩存,單個客戶端高速緩存可以提高速度。通常,您緩存您知道在特定時間段內不會更改的數據。當時間間隔過去後,您將數據強制從緩存中移出或標記為“過時”,以便在下一次請求後刷新數據。

重要說明:根據我的經驗,最好的中間層是沒有任何業務邏輯的層。業務邏輯應該駐留在數據庫和UI中。中間層應該是數據庫基本功能中高度可配置的通用網關,並且不應在每次擴展業務邏輯時都進行修改。我用C#和Java在我的生活中多次構建了這樣的中間層。

也許第二個最好的中間層是在添加新的業務邏輯時僅需要較小的和標準化的修改的層。我也曾多次與這樣的中間層合作過。

運行項目

客戶端 - 服務器API要求傳播原則

多層開發的主要原則是客戶端應該比他實現它的API有更多的發言權(API應該由客戶端驅動)。

正如軟件的客戶(或客戶端代理,如產品經理)對最終產品的外觀應該有更多的說法,UI開發人員也應該對他從中間層使用的API有更大的發言權,後端。

我想清楚2點:

  1. 我並不是說UI開發人員完全確定了API。應該在請求者和實現者之間的討論中明確API - 有些事情可能不可能或很難實現。

  2. 服務器的實現仍然取決於服務器開發人員 - 我只談論客戶需要的公共API。

技術分享圖片

UI開發人員和後端/中間層開發人員之間的關系應該與最終用戶和UI開發人員之間的關系完全相同

這個原則通常不被遵循。實際上,人們從後端和中間層開始開發,然後UI必須圍繞所有由此產生的API問題進行論述。

想象一下,UI開發人員會來到最終用戶,並告訴他們,即使他沒有與他們進行任何咨詢,他所建的東西也能滿足他們的需求。聽起來相當荒謬,但是UI開發人員不得不經常處理類似的情況,當後端開發人員告訴他們現在他們擁有他們所需要的所有東西,即使他們沒有與UI開發人員進行任何咨詢。

我的經驗一次又一次地證實了這個原則 - 需求,APIs甚至開發都應該從使用API的部分傳播到實現它的部分。這不僅適用於客戶端 - 服務器部門,也適用於您自己編寫重要軟件的情況。你需要從軟件的目的開始,然後填寫‘空格‘。否則,如果你從‘空白‘開始,你可能會發現他們不太適合這個目的。

測試驅動開發的普及是對這種範式的另一種證實。

創建API

在傳統的‘瀑布‘哲學中,建築師試圖在項目的一開始就創建很多接口,以便開發人員能夠為他們編程。從我的角度來看,這不是最好的方法 - 它把馬車放在了馬匹的前面。

在開始時應該創建很少的接口,並且架構師應該隨時準備修改它們,如果發現它們不符合目的。

應該在需要時創建接口 - 例如,只要有方法或類需要處理滿足某個接口但實現可能會有所不同的對象時。不要過於努力地預見,你需要一個接口 - 首先(當只需要一個實現時)編程到一個類,但是當出現這樣的需求時,準備將它改變為一個接口。

這在個人層面和建築師層面都是如此。敏捷的叠代特性能夠適應API修改。

建築師的角色

這將我帶入軟件架構師的角色。

團隊中的一位開發人員可以承擔建築師的角色(特別是在項目大小合理的情況下)。

這是軟件架構師應該承擔的任務:

  1. 概述發布過程 - 將產品移至用戶或用戶代理。

  2. 隨時關註產品開發進度和產品需求變化。

  3. 在開始階段 - 如上所述構建產品的非常稀疏的骨架(原型)(包括初始測試項目)。

  4. 解決各種開發人員之間的軟件問題。

  5. 找出代碼共同點並將它們分解成可供各種開發人員在各個地方使用的通用API。

最後一點也應該由各個開發人員為他們自己的代碼實施,或者如果開發人員在多個開發人員領域中看到代碼的共同性,他應該將其引入共同考慮範圍,並讓架構師決定是否需要分解通用性。

一般來說,代碼中的共同點應該不斷重構,無論是由開發人員還是架構師。

有些人認為他們需要提前找出並排除所有共同點。這不太可能。沒有人能夠做到這一點,就像沒有人能夠在項目開始時創建所有界面一樣。沒有理由花大量時間在一開始就考慮個人或架構師層面的共同點。在整個代碼開發過程中,您將能夠找到要重構的代碼。

我對建築師的建議是在整個多層架構中考慮數據形狀。在關系數據庫中 - 數據通常放置在規範化的表格中。也有一些記錄可能通過實時提要進行傳播。該級別沒有層次結構。然而,在UI方面,大多數記錄需要一些層次結構,以用戶想要的形狀顯示給用戶。我打算寫另一篇專門討論數據形狀和數據形狀轉換的文章。

建立一個團隊

根據我的經驗,工作場所以外的非工作相關活動是建立人與人之間信任並讓人感覺自己是團隊的好方法。以下是一些可行的活動:

  1. 清道夫狩獵

  2. 去一家餐館或喝一杯

  3. 足球比賽

  4. 保齡球

人的問題

以下是我在整個項目中觀察到的一些與人相關的問題

  1. 良好的領導能力和政治技能不足以執行一個項目。事實上,我看到項目失敗了,因為他們是由具有良好領導才能和政治技能的人領導的,但沒有任何軟件開發意識或有一些軟件開發意識,但不敢用它來反駁上司。

  2. 在會議上充滿自信地發言的人不一定知道軟件細節。重要的決定決不應該在一次會議上進行 - 只有在徹底的書面討論之後。

當沒有線索的人試圖接管某個領域的編碼或項目領導時,我觀察到了所謂的“庸醫”問題。他們可能具有良好的領導能力和演講技巧,其中一些甚至可能擁有技術技能,但在不同的領域。不應允許這些人在他們不知道的領域做出決定。

檢查一個人是否是某個領域的專家的一種方法是讓他建立一個概念驗證原型。如果他不能建立一個小概念證明,他不應該被允許接管這個項目。

我曾與一位表示制作原型的人合作需要太多時間,並且每個人都只是跟隨他的領導或者整個項目都將崩潰。這種“全部或全部”的方法肯定是一種尷尬的跡象 - 應該始終可以建立一個小概念證明。這個人不得不離開這個項目,沒有他,項目就成功了。

面試候選人

我在職業生涯中進行了許多面試,這裏有幾點我想分享一下:

  1. 切中要害 - 如果你想聘請Angular專家,不要問他關於WPF或SQL的許多問題。

  2. 例如,測試概念並不是細節,例如,測試人們對關系數據庫概念的理解總是很好的,但是(除非你專門雇用SQL專家),你不必在MS SQL Server中測試他對臨時表的了解。

  3. 有時候,記憶力好的人可以通過心靈學習很多信息,然後用它來進行面試。這就是為什麽讓人們真正進入並進行簡單的編碼考試非常重要。這種方式總是可以看出該人是否擁有知識,或者在幾天之前他就簡單地擠滿了所有東西。

編寫,執行和測試要求

這個要求應該在開發者和訂購需求的人之間進行確定 - 它可能是最終用戶,也可能是團隊中的建築師或其他開發人員。由於開發人員的屁股已經上線,開發人員應該經常仔細閱讀這個要求,確保在開始工作之前不要留下任何碎片。

要求(或Jiras)通常應該考慮到單一功能。該功能可能是用戶功能,或者可能是終端用戶永遠不會看到的功能,例如某些重構; 無論哪種方式,大多數情況下,一個要求應該有一個功能。

一旦創建了需求,就不應該添加新的功能請求。它應該作為從請求者到質量保證的路線圖。如果事實證明開發人員實施了這項要求,但是要求是錯誤的或者不完整 - 這是請求者的錯,並且應該打開一個新的Jira來覆蓋剩余的。但是,如果開發人員沒有滿足這個要求 - 這是開發人員的錯,而且需要重新開放並重新分配給同一開發人員完成。

當涉及到UI開發時,也有一些小的,易於實現的需求(我稱之為‘UI煩惱‘),盡管它們可以接觸完全不同的功能,但它們都可以使用到單個Jira。你可以為他們打開特殊的‘尼特‘吉拉,在‘單一功能‘的條件是沒有必要的。

?針對上面的技術我特意整理了一下,有很多技術不是靠幾句話能講清楚,所以幹脆找朋友錄制了一些視頻,很多問題其實答案很簡單,但是背後的思考和邏輯不簡單,要做到知其然還要知其所以然。如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java進階群:744642380,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。

結論

在本文中,我以建築師和開發人員的長期經驗為基礎,提出了啟動和執行多層項目的建議。

我相信遵循這些建議可以大大降低項目成本的時間和金錢,並提高產品的價值。

資深架構師的經驗分享——軟件項目開發和決策