架構師是一種神祕的職位,聽說每一個架構師都有密不可傳的方法,固然咱們不信,更多的是隻可意會不可言傳。就是說了咱們也不會懂,由於還每到「火候」。所能作的就是,當咱們到這種火候的時候咱們能想起來曾經有過架構師這麼說過,而後咱們就能夠更自信的向前大步走....
一、客戶需求重於我的簡歷
要想擁有漂亮的我的簡歷:咱們經常向客戶推薦技術、手段,甚至方法論來解決問題,使用時髦的編程技巧和流行的範式,有時候根本不是尋求解決問題的最佳方案。
積累一批滿意的客戶,選擇切合實際的技術解決他們的難題,讓他們樂於推薦你纔是最好的履歷。
二、簡化根本複雜性,消除偶發複雜性
根本複雜性指的是與生俱來的、沒法避免的困難。好比,協調全國的空中交通就是一個「天生的」複雜問題,必須實時跟蹤每架飛機的位置。
偶發複雜性:是人們解決根本複雜性的過程當中衍生的。
架構師的責任在於解決問題的根本複雜性,同時避免引入偶發複雜性。
怎麼作?儘可能選擇源自實際項目的框架,警戒那些象牙塔裏面的產品。
三、關鍵問題可能不是出在技術上
簡單的項目也會翻船,並且這不是個別狀況。大多數項目是人完成的,人才是項目成敗與否的基礎。
若是團隊裏有人工做方式不正確,拖項目後腿怎麼辦?有一種很是古老但很完善的技術能夠幫助你解決問題。它多是人類歷史上最重要的技術創新,這就是對話。
有幾個簡單的對話技巧能夠顯著改善對話效果:
不要把對話當成對抗。
不要帶着情緒與人溝通。
嘗試經過溝通設置共同的目標。
四、以溝通爲中心,堅持簡明清晰的表達方式和開明的領導風格
溝通必須簡明清晰,沒有人願意閱讀冗長的架構決策文檔,架構師言簡意賅的表達觀點是項目成功的必要條件。
架構師每每忽略了本身也是領導者。做爲領導者咱們必須得到同伴的尊敬才能順利開展工做。全部的成員都但願有明確的溝通和開明的領導。只能這樣才能改善溝通效果,創建團結健康的工做環境。
五、架構決定性能
你們彷佛理解,事實並未如此,有些架構師認爲簡單的更換底層架構就足以解決應用的性能問題,他們極可能輕信了「經測試產品性能超出競爭對手25%」,好比從4ms到3ms,這1ms放在一個性能極低的架構裏幾乎能夠忽略不計。
歸根結底,全部產品和架構必須遵循分佈式計算和物理學的基本原理:運行應用和產品的計算機性能有限,經過物理鏈接和邏輯協議實現的通訊必然有延時。所以,應該認可架構纔是影響應用性能和可伸縮性的決定因素。性能參數是沒法簡單的經過更換軟件,或者「調優」底層軟件架構來改善的,咱們必須在架構的設計和從新設計上投入更多的精力。
六、分析客戶需求背後的意義
顧客和最終用戶一般提出的所謂需求,只是他們心目中可行的解決方案,並非問題惟一的解決途徑,當了解顧客的需求背後的意義,咱們能夠爲顧客解決真正的問題並可能下降難度。
七、起立發言
許多架構師都是從技術崗位上成長起來的,他們擅長和機器打交道,然而架構師更須要與人打交道,不管勸說開發人員接受具體的設計模式,仍是向管理層解釋購買中間件的利弊,溝通都是達成目標的核心技能。
有經驗的架構師會很重視推銷本身的想法也明白有效溝通的重要性,其中一個簡單又實用的技巧是在2人以上的場合發表意見時請「站起來」,起立發言很是重要尤爲是當其餘人坐着的時候。
當你站起來的時候無形中添加一種權威和自信,天然就控制住了場面,聽衆不會隨意打斷你的發言,這些都會讓你的發言效果大爲改觀,你會發現站立能夠更好的用雙手和肢體語言。在10人以上的場合,起立發言方便你與每位聽衆保持視線接觸。眼神交流、肢體語言等表達方式在溝通中的做用不可小覷。起立發言還可讓你更好的控制語氣、語調、語速和嗓門,讓你的聲音傳的更遠。當你講到重點內容時,注意放慢語速。發聲技巧也能顯著改善溝通效果。
比溝通事半功倍,起立發言是最簡單、有效的方法。
八、故障終究會發生
硬件會出錯,因而咱們增長冗餘資源來提高系統的可靠性,同時也增長了至少有一臺設備出錯的機率。
軟件會出錯,增長額外的監控程序也會出錯。因而咱們又爲自動化增長監控,結果是更多的軟件,致使更高的故障率。相似的如:三裏島核電站泄漏事故
既然必然會出錯就須要事先設計好防範故障的模型,以應對威脅系統安全的意外狀況。
九、咱們經常忽略本身在談判
咱們都面臨過削減預算的要求,若是資金運轉促襟見肘,技術方案只能委屈求全。
好比以下情景:
「咱們真的須要這東西嗎?」項目投資人發難道。
儘管真的須要,咱們一般也不能這麼回答,由於此時咱們是在談判,此時咱們須要認清本身的角色,不能把本身當成工程師,並且投資人明白他在和你談判,咱們應該這樣回答"真的須要嗎"這類問題:
「單臺服務器天天至少崩潰3次,沒有第二臺咱們甚至沒法跟董事會演示,事實上咱們須要4臺服務器,構成2組,這樣在須要時斷開一組而沒必要被迫關閉系統。即便有一臺出現意外,也不影響系統正常運行」
十、量化需求
速度快不能算做需求,響應靈敏和可擴展也不能算需求,由於咱們沒法客觀地判斷是否知足了這樣的條件。
正確的描述需求應該像這樣:「必須在1500ms內響應用戶的輸入。在正常負載下,平均響應時間控制在750ms-1250ms之間。因爲用戶沒法識別500ms之內的響應,因此咱們不必將響應時間降到這個範圍一下。」
十一、一行代碼比500行架構說明更有價值
架構說明書(specifications)很重要,由於它描述了構建系統的模式,可是靜下心來全面完全地理解架構——即從宏觀上把握組件之間的交互,又着眼於組件內部的代碼細節——也很重要。
架構師每每容易被抽象的架構所吸引,沉迷於設計過程。事實上僅有架構說明書是遠遠不夠的。軟件項目的最終目標是創建生產體系,架構師必須時刻關注這個目標,牢記設計只是達到目標的手段,而不是目標。
若是親自開發,應該珍視本身花在寫代碼上的時間,千萬別聽信這會分散架構師精力的說法。這樣既能拓展你的宏觀視野,也能豐富你的微觀世界。
十二、放之四海皆準的解決方案
架構師應該堅持培養和訓練「情景意識」——由於咱們遇到的問題千差萬別,不存在放之四海皆準的解決方案。
「情景模式」:調查有經驗的架構師處理複雜問題的方式。有經驗的架構師和設計師的答案一模一樣:只須使用常識....【一個】比「常識」更貼切的說法是「情景意識」——在給定情景下對合理性的把握。架構師經過學習和實踐,不斷積累的案例和經驗,創建足夠的情景意識。他們一般須要十年的磨練,才能解決系統層次的問題。
1三、提早關注性能問題
商業用戶的需求主要表現衛隊功能的要求。系統的非功能特性則由架構師負責,包括:性能表現、靈活性、持續正常工做時間、技術支持資源等。可是對非功能特性的初始測試每每被拖到開發週期的最後階段,有時還由開發團隊來操刀,這樣的錯誤家常便飯。
在項目週期的最後階段才關注性能問題,會致使咱們錯失大量歷史信息,這些信息包含性能變化的細節。若是性能是架構設計的重要指標,就應該儘早展開性能測試。在採用敏捷方法開發的項目中,若是有2周爲一個迭代週期,我認爲性能測試的開始時間最遲不能晚於第三次迭代。
堅持技術測試是須要耐心和毅力的,不管是搭建合適的測試環境,採集適當的數據集,仍是編寫必要的測試用例,都須要投入大量的時間。
1四、架構設計要平衡兼顧多方需求
平衡兼顧各方的要求和項目的技術需求
CEO須要控制成本
運營部門要求軟件易於管理
二次開發人員要求軟件代碼容易學習方便維護
業務部門:旅行合同義務、創造收益、樹立客戶口碑、控制成本,創造有價值的技術資產
技術部門:確保軟件的功能
1五、草率提交任務是不負責任的行爲
傍晚時候,團隊正在完成本次迭代的收尾工做,一切循序漸進、有條不紊。只有約翰趕着赴約有些急躁,他倉促寫完本身的代碼,編譯、檢入,而後匆匆離開。幾分鐘後紅燈亮起(許多采用敏捷開發方法的軟件公司(例如ThouthtWorks)在每一個團隊成員的桌上放置一盞3色燈,用來表示當前的集成狀態,黃色正在集成,綠色集成成功,紅色集成失敗),構建失敗。約翰沒來得及執行自動測試就草率地提交了任務,連累你們沒法繼續工做。正常的工做秩序全被打亂了。
這個時候架構師就該發揮做用了,營造一種團隊文化,以維護流程通暢爲重,以浪費他人時間爲恥。要作到這一點,務必在系統內實現完善的自動測試功能,糾正開發人員的行爲。
沉下心來改變系統的生產效率,縮短流程避免各行其是,才能縮短開發時間。總之必定要杜絕一切草率提交任務的念頭。
--------------------- 程序員
1六、不要在一棵樹上吊死
負責構建系統的人彷佛沒法接受這樣的事實:沒有哪一種數據類型、消息格式、消息傳送機制,甚至主流的架構組件、策略、觀點用來可以用來解決全部的業務問題,畢竟當你們都但願擺脫業務需求不斷滋生的意外和煩惱。
才用多鐘錶現方式、多鍾傳輸方式不是爲了消遣。應當認識到,經過分解系統的非功能參數,能夠爲客戶提供多樣化的解決方案。
1七、業務目標至上
在商業化的背景下開發企業應用,架構師必須成爲業務部門和技術部門溝通的橋樑,周旋調解,兼顧雙方利益,同時業務目標來驅動項目 開發。業務目標和實際的開發條件應該成爲架構師主持制定決策的參照系統。
在啓動一個軟件項目以前,應當制定計劃,明確投資回報的預期。架構師必須把握這個預期,並預估該項目的商業價值,避免作出錯誤的技術決策,形成經費超支。
用業務目標驅動項目開發,才能保證軟件開發團隊的長遠利益。
1八、先確保解決方案簡單可用,再考慮通用性和複用性
許多用來實現基礎設施的代碼,包括組建、框架、類庫、基礎服務,廣泛存在一個問題,它們設計一貫強調通用性而不考慮具體應用。
若是存在多個可實施方案難以取捨,「先簡單後通用」原則能夠成爲最終的評判標準。
雖然不少架構師重視通用性,但這樣作是有前提條件的。並不是全部人都須要通用性,願意爲它掏錢。
1九、架構師應該親力親爲
稱職的架構師應該經過示範領導團隊,架構師一般都取得過不錯的業績,有份出彩的簡歷,容易得到業務人員和技術人員的青睞。但除非他能展現本身的實踐能力,不然很難贏得團隊的尊重,團隊成員將沒法從他身上學到東西,你們甚至難以在他的領導下作好本職工做。
20、持續集成
架構師(不管是應用架構師仍是企業架構師)都應該在項目中鼓勵推廣持續集成的方法和工具。
如今持續集成已經取代了「儘早構建,常常構建」(build early and often)的提法,它確保當前的開發不會出現意外,是一種下降風險的技巧。
構建應用程序是持續集成最主要的內容,它一般是自動執行的,能夠設置在夜裏執行,或者當源代碼改變時自動觸發。固然你也能夠選擇手動構建。
2一、避免進度調整失誤
致使項目失敗的緣由不少,最多見的是中途臨時調整進度。
改變計劃回答帶來如下問題:
倉促的進度會致使拙略的設計、蹩腳的文檔,可能引起質量問題,致使用戶拒絕簽收
倉促完成代碼致使bug增多,測試不充分增長測試中可能出現的問題
以上問題均能引起產品質量問題,而解決產品質量的問題代價更高。最後的結果是成本不降反升,一般項目就是這樣失敗的。
2二、取捨的藝術
架構師應該明白魚和熊掌不可兼得的道理。若是2個性能自己就是衝突的,知足一項就會致使另外一項失敗或者總體失敗。
2三、打造數據庫堡壘
建立牢固的數據模型要從第一天開始
牢固的數據模型既能夠保障當前的數據的安全,又爲從此提供可擴展性。要保障數據安全就必須隔離來自應用層的bug(在不斷變化的應用層中這些bug無處不在,不會由於你的勤奮而消失),必須嚴格遵照引用完整性規則,儘可能使用域約束規則,還要選擇恰當的鍵,即保證數據的完整性,又遵照約束規則。要實現可擴展性,就必須正確地將數據標準化。以便從此在數據模型上添加架構層:千萬不要偷懶走捷徑。
爲了妥善保護數據庫必須拒絕無效數據,阻止無心義的關係。在定義鍵、外鍵、域約束時,應該採起簡潔的容易被理解和驗證的名稱,使他們含義不言自明。數據模型中的域規則也要作到物理化和持久化,避免他們在應用邏輯發生改變時被刪除。
爲了充分發揮關係型數據庫的做用——讓它真正的成爲應用的一部分,而不只僅是存放數據的庫房——必須從開始構建數據庫時,就深入理解業務需求。隨着產品的演變,數據層也會發生變化。
2四、重視不肯定性
當你面臨2中選擇的時候應該仔細考慮設計中的不肯定性。
迫於壓力,人們經常爲了決策而決策。這時能夠借鑑期權思想(指在期貨交易中,權利的受讓能夠在未來的某個約定的時間,根據當時的狀況決定是否行使權利,即推遲作決定時間),當你在不一樣的系統開發路線之間猶豫不定時,不要急於作出決策。推遲決策,直到掌握更詳實的信息,以便作出更可靠的決策。但也別太遲,要趕在這些信息失效前利用他們。
2五、不要輕易放過不起眼的問題
問題出現時,雖然個別團隊成員會發現一些端倪,但每每因爲大多數人認識不到其嚴重性,這些問題不是被忽略就是被擱置,知道變得難以解決。
注意形成的緣由和哪些方法克服這些消極因素。
2六、讓你們學會複用
有這樣一種觀點,認爲設計優良的框架、細緻考慮並精巧實現的架構天然會被人們重複利用。
但也是在知足下列條件下擦可能被複用:
你們都知道它的存在
你們知道如何使用它們
你們認識到利用已有資源好過本身動手
2七、架構裏面沒有大寫「I"
英文單詞架構(architecture)裏面有字母」i"但不是大寫的「I」。它表明的不是那個喜歡喚起別人關注,喜歡凌駕於衆人之上的「I"(自我)。
自我多是咱們這最大的敵人。
如何避免犯錯誤?
需求不會撒謊。
重視團隊合做。
檢查你的工做。
自我檢討。
2八、使用」一千英尺高「的視圖
用來了解正在開發的軟件質量如何
在架構圖中,系統是由若干個小方框組成的,方框之間的連線表明着各類含義:
依賴關係、數據流、共享資源等。
這種圖比如從飛機上俯瞰地面上的風景,咱們稱之爲「三萬英尺高」的視圖。另外一種典型的視圖是源代碼,比如佔在地面上看大地。兩種視圖都沒法衝分鐘展示軟件的質量:前者太抽象,然後者細節太多,以致於咱們看不清整個架構。很顯然咱們須要一個介於2着之間的視圖——「一千英尺高」的視圖。
"一千英尺高「的視圖提供的信息來自恰當的層次,囊括大量數據和多鍾度量標準,例如方法數,類扇出數和圈複雜度。具體的視圖與特定的質量屬性密切相關。
一旦咱們繪製出合適的視圖,判斷軟件質量就更客觀了。
2九、先嚐試後決策
建立一個應用須要做出不少決策。有些決策設計挑選框架和函數,而另外一些則須要選定特定的設計模式。
架構師應該持續關注那些立刻要制定的決策,架構師能夠在決策以前,要求幾個開發人員商量解決方案,比較不一樣解決方案的優勢和弊端。
對同一個問題嘗試2種或者2種以上的解決方案,多是代價最低的選擇。過後發現方案不合適或者是沒人發現方案不合適都是糟糕的狀況。
30、掌握業務領域知識
高水平的軟件架構師不只要懂技術,還要掌握問題空間對應的業務領域的知識。缺少業務領域知識的架構師不能順利地解決問題,沒法把握業務目標和業務需求,也就難以設計有效的架構來知足需求。
3一、程序設計師一種設計
程序設計屬於設計範疇而不是生產範疇。
軟件的生產則是自動化的,由編譯器、構建工具和測試代碼共同完成。
若是把編寫代碼當作設計行爲,而不是生產行爲,咱們就能採用一些已經被證實有效的管理方式。這些方法過去用於管理不可預測性的創新工做,好比研發新車、新葯、新的電腦遊戲。咱們指的是敏捷的產品管理方法和精益生產方法,好比SCRUM。
3二、讓開發人員本身作主
多數架構師都是從開發人員幹起的。之前做爲開發人員你不多有機會仔細觀察整個系統是怎樣組合在一塊兒的,而做爲架構師這是你工做的重點。
若是想出色的完成工做,是不可能有空閒去幹預開發人員的。
3三、時間改變一切
選擇值得投入精力的工做
簡單原則,回顧之前或者更早的項目時,幾乎都會驚詫本身當初的作法,若是有機會再作一次,咱們必定會以更簡單點的方法來完成。這就是時間的做用。
別跟之前的工做過不去,你如今看重的設計思路,可能2-3年後就會被本身否認。
3四、設立軟件架構專業爲時尚早
設計軟件架構師一門手藝,從業者無心要經過實踐和訓練才能在這個領域得到成功。
3五、控制項目規模
估算與準確的科學計算相差甚遠,因此產品特性實現起來經常比預期要困難。
縮小和控制項目規模策略:
抓住真正需求。分而治之,設置優先級,儘快交付。
敏捷方法的倡導者提倡開發」最簡單有用的東西「,越複雜的架構越難以實現。縮小項目規模一般會下降架構的複雜性,這是架構師提升成功概率最有效的途徑。
3六、架構師不是演員,是管家
架構師接受新項目,都渴望證實本身的價值,這是人之常情。
炫耀和做秀與指揮開發項目背道而馳。
架構師的職責和管家相似,承擔着管理他人資產的責任。
架構師要知足不一樣領域的客戶需求,而這些領域的專業知識一般是架構師所不具有的。
3七、軟件架構的道德責任
軟件世界的道德範疇邊界並不清晰,儘管有些行爲無疑是不道德的,好比侵犯他人的公民權利等,但還有些行爲的道德意義不被察覺,好比浪費別人的時間。
架構師的每項決策(例如設置必填項和規定流程),都限制了用戶能夠作什麼不能作什麼。這比法律容易的多,而且還找不到法院受理他們的訴訟。
咱們能夠從倍增效應的角度來看待軟件的影響。軟件問題所形成的損失將以成不可估量的倍數出現,尤爲是給人心理上的。
假設架構師要實現一個新功能,簡單的設計要1天完成複雜的設計要1周的時間,但簡單的設計要強迫用戶輸入大量的數據,這個過程經常會丟失數據,耽擱工做,讓人很是沮喪。從長遠看浪費別人的時間將遠遠超過你省下的時間。
損人利己是不道德的行爲哪怕程度很輕。
3八、摩天大廈不可伸縮
土木工程不僅是設計建築這麼簡單,真正的難題在於規劃整個施工過程,確保建築物拔地而起,包括從奠定到竣工的全部工做。其中有不少經驗值得咱們借鑑,尤爲是對於部署大型集成化軟件系統(包括全部企業應用和web應用)。若是把軟件比喻成土木工程,那麼傳統的大爆炸式軟件部署方式就比如把備齊的建築材料一股腦仍上天,期望他們瞬間拼成一座大廈同樣那麼好笑。
相反,不管是開發新項目,仍是替換已有的系統,都應該逐個部署系統組件。2個優勢:首先,隱藏在代碼中的技術風險是部署軟件時沒法迴避的問題,其次這種方法迫使咱們設計清晰的組件間接口。
有些是不能借鑑的,尤爲是在建築工程中屢試不爽的」瀑布式「施工方法。畢竟摩天大廈不須要可伸縮性。
應用軟件只要具有了用戶要求的功能即可發佈,不用等到十全十美。事實上,產品越早發佈公司的淨收益就越高。這樣既可增長商業利潤又能夠改變架構品質,這樣實用的技巧實在很少。
3九、混合開發的時代已經來臨
混合編程:在一套軟件系統中同時採用多種核心編程語言
如今能夠採用基於文本協議(text-based protocols)了。這些新技術以特定格式的文本做爲載體,便於全部人編寫和理解,爲混合開發提供了史無前例的可能性。
架構師把若干個強大的開發工具組合起來使用,以往的標準是挑選合適的編程語言,如今則演變成挑選合適的編程範式。
選擇多了並不老是好事,但至少好過以往軟件架構非此即彼的窘境。
40、性能至上
性能指標和其餘指標同樣重要。
有些設計師把性能放到最後考慮。
咱們一般把系統響應用戶輸入的時間做爲衡量性能的標準。
生產率一般用來描述構架系統的效率,也屬於性能範疇,其重要性在於直接影響項目的成本和進度。
系統的人機交互性能直接關係到用戶是否願意掏錢。包括:響應時間,是否直觀,操做步驟是否簡單。
合格的說明書除了註明系統每秒鐘的響應次數,還要測量典型的任務時間。
非交互性組件的性能一樣影響着系統的表現。
在考慮系統的實現方法和運維策略時,架構師和設計師應該密切的關注系統的性能表現。
4一、留意架構圖裏面的空白區域
軟件系統由相互依賴的程序組成,咱們把裝配這些程序的方法及程序之間的關係成爲架構。
假設某個箭頭表示」使用HTTP協議,發送SOAP-XML格式的同步請求/響應消息「,因爲架構圖裏面的空間有限,寫不了這麼多內容,因此一般用簡單的註釋表示。從技術角度出發能夠簡寫成」XML over HTTP",若是從業務角度出發,有可能寫成「查詢庫存單元」。不一樣的程序看似經過箭頭直接聯繫,其實否則,矩形之間的空白區域充滿 着各類軟件和硬件。
應該理解每一個箭頭包含的靜態信息和動態信息。
4二、學習軟件專業的行話
每一個專業都有行話,同行之間講行話方便交流,清晰、簡潔、高效的方式與同行進行溝通,是軟件架構師應具有的能力。架構師必須掌握基本的架構模式和設計模式,學會辨別不一樣模式,並藉助他們和同行及開發人員進行交流。
架構和設計模式能夠分爲四大類:企業架構模式、應用架構模式、集成模式、設計模式。
企業架構模式定義架構的全局框架結構。
應用架構模式指出了全局架構下的子系統及局部應用的設計方法。
設計模式研究架構中各個組件的構造方法。
除以上4種外,架構師還應該瞭解和提防各類反模式。
反模式:影響軟件開發中的常見錯誤:需求分析麻痹症、委員會設計、蘑菇管理、死亡征途。
4三、具體情境決定一切
」分享設計架構的理念讓我以爲很滑稽,由於我認爲壓根就不存在設計理念「
「畢竟,沒有理念自己也是一種理念」
最重要的設計經驗是具體情境決定一切,根據它設計儘可能簡單的解決方案。換句話說,架構決策只有在情境須要時,才能犧牲儘可能簡單的原則。
脫離了具體的應用場景,孤立地比較技術的優劣是毫無心義的事。
4四、侏儒、精靈、巫師和國王
架構師比如國王,應該熟悉各類人的性格特色,招聘不一樣性格的人加入本身的團隊。
安排任務時應該時刻考慮全部開發人員的性格特色。爲不一樣性格的團隊成員安排合適的任務,若是你們有機會磨合、相互適應,就能輕鬆化解決各類難題。
4五、向建築師學習
建築師名言
建築師社會性的表演,是上演人類歷史的劇院。
要想成爲偉大的建築師,優雅豐富的心靈遠比聰明才智重要。
.....
建築師自誇上帝的助手,甚至覬覦上帝的寶座。(上帝:客戶)
天底下沒有完美的建築。
建築師首先應該是偉大的雕塑家,或者偉大的畫家,不然他不過是個建築工人。
---------------------
4六、避免重複
你的開發人員在重複無需思考的工做嗎?代碼裏面反覆出現某些類似的片斷?某些代碼是複製粘貼後稍加修改而成的,若是出現這些狀況,說明團隊工做效率不高。
軟件開發的真理:複製時魔鬼
重複性的工做拖累開發的進度。
消滅重複的內容是你的責任,爲此,應該從新研究框架,創造更完善的抽象機制,請專門製做工具的程序員(toolsmith)幫你完成切面框架(aspect framework),使用代碼生成器。要想消滅重複內容必須有人採起行動。
4七、歡迎來到現實世界
工程師偏心精確,成天和0和1打交道的工程師更是如此。
現實世界不是二進制的。顧客有可能撤銷確認過的訂單,支票有可能跳票,信件可能丟失,付款時間可能延遲,許下承諾還可能失信。
這些已經夠糟了,可分佈式系統又帶來了新的不一致性。服務有可能失效,狀態有可能在毫無徵兆的狀況下改變,事務處理可能得不到保證。
分佈式系統不可是鬆耦合、異步、併發的,並且不遵照傳統的事物語義。
4八、仔細觀察別試圖控制一切
妄想掌控一切的架構師只能設計出緊耦合的、脆弱的解決方案,這一套已經行不通了。咱們必須啓動必要的輔助機制。
咱們已經進入分佈式、鬆耦合系統的時代。構建鬆耦合的系統多少有些麻煩,咱們但願系統足夠靈活,別由於一點點小的改動就支離破碎。
隨着系統的配置愈來愈靈活,當前的系統配置包含了更多的信息,爲了便於理解,必須從中提取模型。好比,搞清楚哪一個組件負責向邏輯信道發送消息,哪一個組件負責接收消息,就應該把組件間的通訊關係用圖標模型記錄下來。
與模型驅動架構不一樣,你先構建出靈活的架構,而後從實際的系統狀態中提取模型。
4九、架構師比如兩面神
羅馬神話裏面,兩面神是司守門戶和萬物始末之神。他有兩張面孔,凝視2個不一樣的方向。
兩面神兼顧先後,過去與將來。架構師在不一樣的對象之間架起橋樑,好比夢想和現實、過去的成功和將來的方向、業務目標與開發i限制。
咱們應該以兩面神爲榜樣,工做上嚴格把關,綜合考慮新狀況與老經驗,在成熟技術上不斷創新,既知足當前的業務需求,又兼顧將來的額發展規劃。
50、架構師當聚焦於邊界和接口
「哪些應該在一塊兒,哪些應該分開」
5一、助力開發團隊
架構師能夠施加約束,也有機會成爲推進者。
要確保開發人員擁有他們所需的工具。
要確保開發人員擁有所需的技能,確保他們可以得到必須的培訓。
同時,也要儘量的參與到開發人員的選拔中。
只要不違背軟件設計的整體目標就讓開發人員本身作決策。
最後,保護開發人員,不要讓他們捲入到不那麼重要的工做中。
5二、記錄決策理由
在軟件開發社區,對於文檔尤爲是關於軟件自身設計的文檔的價值,爭論頗多。分歧通常集中於兩處,一處是「詳細的前期設計」的有效價值,另外一處則是使設計文檔化和不斷變化的代碼庫保持同步的難易程度。
記錄軟件架構決策理由的文檔,長期有用,無需爲之付出過多維護精力,具備很高的投資回報價值。
根據項目的不一樣靈活選擇合適的文檔格式來記錄架構決策的方方面面,格式能夠是文本、維基、或博客形式的速記備忘錄,也能夠使用較正式的模板。
好比這些文檔:
能夠做爲和開發人員溝通的工具,說明應遵循的重要架構原則
當開發人員對架構背後的邏輯提出質疑時,使團隊可以就事論事
向經理和利益相關者說明這樣構建軟件的確切緣由
把項目移交給下任架構師
好處是:
它逼着你說出理由時,有助於確保基礎是紮實穩固的、
若是相關條件發生變化,須要對決策從新評估,它能夠做爲一個起點
5三、挑戰假設,尤爲是你本身的
延遲判決法則:「臆斷是事情搞砸的根源」
軟件架構師的最佳實踐代表,應該記錄下每一個決策背後的理由,當這一決策包含權衡(性能vs.可維護性,成本vs.上市時間等)時尤須如此。
有些小道消息:
開源軟件不可靠
位圖索引帶來的麻煩比好處多....
確保這些假設清楚明確,對後繼者和將來的從新評估來講很是重要。更重要的是拿出證據。
不要忽略相關這個詞語。
事實和假設是構建軟件的兩大支柱。務必確保軟件的基石堅實可靠。
5四、分享知識經驗
從全部的失敗的經驗中,咱們能夠學到不少東西。在像軟件開發這般年輕的行業中。爲了持續發展傳播經驗和知識相當重要。每一個團隊在本身的小世界小角落裏所學到的東西,可能會在全球產生影響力。
5五、模式病
人們記錄和發現模式,避免後來人從新發明車輪。
對於軟件架構師而言,設計模式是極有價值的可用工具之一。使用模式,可以創造更易溝通更易理解的通用解決方案。模式與良好設計息息相關,若是發現本身試圖把最喜歡的模式硬套在不適用的問題空間上,那麼你也許是」模式病「患者。
不要讓一展模式功底的慾望遮掩了務實真知。
5六、不要濫用架構隱喻
架構師喜歡使用隱喻(metaphor)。對那些一般比較抽象、複雜和變化的移動的目標,隱喻提供了良好的具體媒介。找到實物做爲正要構建的東西的隱喻,會更容易溝通和討論架構全局。
濫用架構隱喻常常會出現問題,讓架構師不知所措,好比:
業務領域的客戶開始愈來愈喜歡系統隱喻,這時,系統還在構想中,在這種狀況下全部各方共享的是最樂觀的可能解讀,但其中並無包括任何須要的約束。
開發團隊認爲隱喻比實際業務更重要。因爲團隊耽溺於隱喻,你不得不開始修正那些古怪的決策。
所交付的系統包含了許多遺留名稱,從早已老舊過期,有待從新鑑定隱喻,到屢次重構和重複挖掘的概念。
5七、關注應用程序的支持和維護
應用程序的支持和維護永遠不是過後才考慮的事情。因爲應用程序80%的聲明週期都在維護上。
開發人員和支持人員擁有的技能不一樣,就像開發/測試環境和生產環境有大相徑庭的目的同樣。
系統管理員會遇到的問題:
*系統管理員不能從新提交請求消息來重現問題。
*一旦投入使用,就沒有調試器能夠用了。
....
就會出現如下症狀:
*大多數問題都須要開發人員參與。
*支持團隊討厭新的應用程序。
....
爲了確保應用程序脫離開發人員之手後能成功運行,應該作到:
*理解開發人員和支持人員確實具備不一樣的技能
*在項目中儘早的引入支持負責人。
...
當系統管理員很開心的時候你們都會很開的。
5八、有舍纔有得
有時,接受某種約束或放棄某個特性,可帶來更好的架構,這種架構在構建和運維上都會更加簡單,並且成本更低,每每能產生富有創造性和創新性的結果。
5九、先考慮原則、公理和類比,再考慮我的意見和口味
若是是單憑我的經驗、意見和口味建立的架構是沒有考慮原則、公理、和類比所帶來的好處的。
這樣作,架構文檔化會更容易,從描述架構所遵循的原則開始便可。
原則清晰的架構可以把架構師解放出來,使其免於全面複審而忙得不可開交。
原則和公理確保了架構的一致性。
60、從「可行走骨架」開始開發應用
爲了實現、驗證和不斷髮展應用架構,一個很是有用的策略,即是從Alistair Cockburn所謂的「可行走骨架」開始。「可行走骨架」是對系統的最簡單實現(a minimal implementation),它貫穿頭尾,將全部的主要構件組件鏈接起來。從可工做的最小系統開始訓練所有的通訊路徑,能夠帶來「正朝着正確的方向前進」的信心。
對於大型系統一般是由多名開發人員共同構成,對於大型系統而言更多的協調工做是必不可少的。
從「可行走骨架「開始,保持系統一直運行可用,遞增式地進行培育,使其逐步增加。
---------------------
6一、數據是核心
軟件開發人員最初將軟件理解爲命令、函數和算法構成的系統。
若是稍稍後退站遠一點,計算機只不過是能訪問與操做一堆數據的時髦工具。
代碼在計算機中運行時,底層數據的狀態不斷髮生變化。
舉例而言,若是想了解Unix操做系統,經過源碼逐行挖掘是不大可能奏效的,可是若是你讀過一本unix內部數據結構的書,即可更好的瞭解unix底層是如何運行的。從概念上開看,數據比代碼更加精煉,也更好理解。
即便對於最複雜的系統,經過這種面向數據的視角,即經過底層信息的結構總體開看待系統,也能夠將之縮減爲細節的有形集合。而後下降其複雜性。
數據在大多數問題中處於核心地位,業務領域問題由數據蔓延到代碼中。
誠然,軟件架構中的許多問題確實和數據相關。
從設計角度來看,大多數系統的關鍵問題,就是要在正確的時間從系統獲取正確的數據。
6二、確保簡單的問題有簡單的解
軟件架構師解決了許多很是困難的問題,但也會解決一些相對容易的問題,對於簡單的問題,不要使用複雜的解決方案。
爲複雜問題付出的直接成本可能看上去很小,可是其潛在成本要大得多。爲問題的解決方案付出的代價不只僅只是在實現和維護上。
架構師會從主觀的判斷或潛在不肯定性需求出發,產生調整解決方案的強烈衝動。但記住一點:試圖猜想將來的需求時,錯的機率是50%,錯的很是離譜的機率是49%。
6三、架構師首先是開發人員
無論解決方案多麼優秀,決定實現可否成功的最重要因素之一是讓開發人員願意接下任務。
雖然不是工做的一部分,架構師仍是會常常去處理一些比較複雜的任務。這樣作的目的有兩個:第一,這是一種樂趣,並且還能幫咱們作到寶刀不老;第二,這有助於向開發人員代表,我不是碰到麻煩時會幹吹菸捲卻一籌莫展的架構師。
6四、根據投資回報率進行決策(ROI)
咱們對項目所作的每個決策——不管是技術、過程,仍是與人相關——均可以看作一種投資形式。
回報率(rate of return),也成投資回報率(Return On Investment,ROI),是衡量投資是否成功的標準之一。
將架構決策視爲投資,並將相關的回報率也一併考慮在內。在判斷每一個決策選項是否務實或恰當時,這種方法頗有用。
6五、一切軟件系統都是遺留系統
即便系統十分前沿,採用了最新的技術開發而成,但對接手它的下一我的而言,它也會是遺留系統(legacy)。必須面對這種狀況!在今天,軟件很快便會過期,這已經成爲軟件的自然屬性。若是軟件可以存活下來哪怕只有數月的時間,都必須認可一點:負責維護工做的開發人員確定要對軟件進行缺陷修復,這是不可避免的。這引出以下幾個問題。
*清晰性:各個組件和類的角色必定要清楚
*可測行:系統易於驗證嗎?
*正確性:結果和設計或指望的一致嗎?
*跟蹤性:可容易修復緊急缺陷
6六、起碼要有2個可選的解決方案
對於某一個問題,若是隻考慮了一個解決方案,那你就有麻煩了,在給定的約束條件下,尋找問題的最佳方案,指望第一個解決方案即知足所有的需求和約束,幾乎是不可能的。
這種問題即便有——也絕少是真地因爲缺少可選方案而形成的,它更多是架構師缺少特定問題域的經驗所致。
6七、理解變化的影響
好的架構師可以將複雜性降到最低程度,他在解決方案中給出的抽象,應該可以爲更高的層次提供堅實基礎,同時,還應該能足夠務實地應付將來的變化。
優秀的架構師可以深入理解變化帶來的影響,這種影響不只限於彼此隔離的軟件模塊之間,並且包括人與人之間,以及系統與系統之間。
變化有多種不一樣的表現形式:
*功能需求的變化
*可擴展性需求的變化
*系統接口被修改
。。。。
幸運的是許多工具和技術能夠用以減輕變化的影響:
*進行小規模的增量漸變
*構建可重複運行的測試用例
*跟蹤好依賴關係
*下降複雜性
*自動化重複任務
6八、你不能不瞭解硬件
對於許多軟件架構師,硬件容量規劃問題是一個超出其溫馨區的主題,但它的確是架構師工做的重要組成部分。
若是沒有硬件方面的專業知識,預估待開發系統的硬件配置是很是容易出錯的。比起採購超出實際所需的硬件,爲容量規劃留出預算是更爲經濟的。
6九、如今走捷徑,未來付利息
長遠看來,系統維護將比項目初期的開發消耗更多的資源。
測試:使用測試先行的設計,進行單元測試
碰到架構問題或設計缺陷,做爲架構師,必定要堅持成本還很低廉時就動手。擱置越久,爲之付出的利息也就越高。
70、不要追求完美,足夠好就行
軟件設計師,尤爲是架構師,在評估針對某個問題的解決方案時,會傾向於考慮它是否優雅完美。有些瑕疵只須經由一些調整或迭代重構即可消除。
建議:不要屈服於企圖使設計或實現達到完美的誘惑!把目的設定在「足夠好」就行,當已經達成目標時就停下來。
7一、當心「好主意」
「好主意」會殺死項目。有時候殺傷力會很快見效,但更常見的症狀是:因屢屢錯過的里程碑和不斷攀升的缺陷數量,項目苟延殘喘,最終不治身亡。
「好主意」:那種誘人2的、不用想都知道的、外表無辜、覺得不可能會產生傷害的那種「好」注意。
「好主意」真正的邪惡之處在於它的「好」。
若是出現下列關鍵詞,要當心了:
*若是....會更酷。
*「嘿,他們剛剛發佈了YYY框架的XXX版本。咱們應該立刻升級」。
7二、內容爲王
我見過無數這樣的設計,它們大都永無止境地強調需求、設計、開發、安全及可維護性,但從未關注系統的真正要點——數據。
7三、對商業方,架構師要避免憤世嫉俗
僱主但願偶們可以解決問題,傾聽和了解僱主的業務,是咱們必須掌握的最爲關鍵的技能。
成爲優秀架構師的祕訣之中有一個關鍵要素,那即是:要對工做滿懷激情,但不要是那種帶着憤怒和火氣的「激情」。
7四、拉伸關鍵維度,發現設計中的不足
應用程序的設計輪廓,最初是基於特定的業務需求、所選擇的技術或現有的技術、性能要求、預期的數據量,以及構建、部署和運營上可用的財務資源。不管採用什麼樣的解決方案,都要求能知足或超越當前環境下的要求,成功運行起來,不然這就不稱其爲解決方案了。
拉伸解決方案的關鍵維度,看看哪些方面會遭到破壞。
7五、架構師要以本身的編程能力爲依託
在架構上,架構師都指望可以建立出精巧的設計和完美的抽象,來優雅的解決手頭的問題。若是能再項目中多安插些技術那就更讓人有成就感了。可是最終要實現設計的不是架構師。若是開發人員須要去實現那些架構上的「雜技」,那將會對整個項目形成巨大影響
爲項目設計架構時,對實現的每一個設計元素所須要的工做量,要作到心中有數;若是之前曾開發過其中某種設計元素,那麼估算所需的工做量將會容易得多。
不要在設計裏面使用本身沒有親自實現過的模式,不要使用本身沒有用之寫過代碼的框架,不要使用本身沒有親自配置過的服務器。
---------------------
7六、命名要恰如其分
若是都不知道一個東西應該叫什麼,那你確定不知道它到底是什麼。若是你不知道它到底是什麼,那麼你確定不能坐下來爲它編寫代碼。
7七、穩定的問題才能產生高質量的解決方案
最好的架構師不是要去解決難題,而是圍繞難題開展工做。架構師要可以將四處瀰漫的軟件問題圈起來,並畫出其中的各類邊界,確保對問題由穩定的、完整的認識。
這些問題應該具備如下特性:
*內聚性:問題塊在概念上市統一的,其中全部的任務、數據和特徵都是相關的。
*可以很好地和其餘塊分隔開:這些塊在概念上進行了規範化處理;他們不多重疊或者根本不重疊。
7八、天道酬勤
架構師經常被描述爲一種注重創造力與問題解決能力的職業。除了創造力外架構師還應當具有另外一項一樣重要的特質——勤奮,勤奮指不少方面,但歸根結底是指具有堅強的毅力,而且對系統的每項任務和每一個架構的目標都能投入足夠精力。
勤奮常常和平凡攜手同行。
勤奮還意味着要求架構師必須真正作好那些看似簡單的任務,堅守承諾。
7九、對決策負責
因爲軟件架構師比組織中的其餘人更有影響力,因此他們必須對本身作出的決策負責。
研究代表有超過三分之二的軟件項目要麼完全失敗了,要麼未能成功交付(項目延期、預算超支、客戶不滿意)。究其根本緣由,有許多事因爲架構師作出了不當的決策,或者沒法最終執行正確的架構決策。
如何作出有效的架構決策:
首先,對決策的過程有充分認識
第二,按期對架構決策進行復審
第三,要貫徹架構決策
最後,能夠將一些決策委託給響應問題域的專家,沒必要出自其自身。
80、棄聰明,求質樸
智力超羣、神機妙算對任何人來講都是值得稱道的品質。對架構師來講,這些素質尤爲被看重。
然而,聰明也包含某些額外的隱含意義。它也暗指能快速想出脫身之計的能力,但這種本領最終要依靠一些小伎倆,騙局或掉包計。
聰明的設計僵硬難改,其細節會對全局產生太多牽扯,每每會一觸即毀。
8一、精心選擇有效的技術,毫不輕易放棄
做爲軟件設計開發的老手,每一個架構師一般都有一些讓本身屢屢取勝的武器用來武裝本身。這些技術因爲種種緣由深受架構師青睞,排在其首選解決方案的前幾位。這並非說某種技術一旦入圍就能夠永久罔替。
選擇新技術雖然有風險,但其價值能爲你帶來質的飛躍。
考慮技術將來的前景。
軟件架構師工做很大一部分,是要選擇用以攻克難題的合適技術。
8二、客戶的客戶纔是你的客戶
在軟件會議需求會議上,要這樣想象:你的客戶並非你的客戶。實際上真的不難作到,由於,事實即是如此。若是你的客戶的客戶贏了,那麼你也贏了。
若是你在編寫一個電子商務應用程序,那麼應該考慮的應當是那些會在那個網站上購物的人的需求。若是你的客戶有意無心的忽視他們的客戶所看重的重要事項——那麼請放棄這個項目。
需求收集會議不是項目實現討論會議。
8三、事物發展總會出人意料
事物的發展總會出人意料。在設計時,人們很容易陷入誤區,投入太多的時間在設計上。
設計中的這些微小變化累積起來,很快就須要對設計進行一次較大的變動。
設計是一個不斷髮現的過程。
8四、選擇彼此間可協調工做的框架
軟件框架是系統的基礎,在選擇時,不只要考慮每一個框架自身的質量和特性,也要關注共同構成系統的各個框架之間是否能和諧相處。
若是框架間有重疊,則要確保瞭解候選框架在邏輯域或關注層面上的重疊程度。
爲了儘可能減小框架間互有重疊的機率,要根據系統需求的應用場合,選擇精專強大的框架。
系統應該由多個相互獨立的框架構成,其中每一個框架都精專於各自的領域,但同時又很是簡潔、包容、靈活。
8五、着重強調項目的商業價值
對於非軟件業從業人員,軟件架構顯得虛無縹緲,架構項目在爭取資金時會遭遇到困難。
大衆心理學代表,大部分人會相信親眼所見的東西。而擁有預算決定權的人,幾乎都是受商業價值驅使的。
下列五部,會成功將架構提案打形成經典的商業項目:
一、造成價值描述(提升 生產力,改進效率的能力)
二、創建量化度量標準
三、回過頭來關聯傳統商業的衡量方式
四、知道該在哪裏中止
五、尋找恰當的時機
8六、不只僅只控制代碼,也要控制數據
源代碼的控制和持續集成,是管理應用程序構建過程和部署過程的優秀工具。數據方案和數據內容經常會根據源代碼的變化而變化,他們也是這一過程的重要組成部分,所以也要對之進行相似的控制。
數據庫的變化不該該影響構建活動的連續性。要把數據庫也做爲一個構建單元包含在內,作到一次性構建整個應用程序。數據遷移不該該做爲一種補救措施。
8七、償還技術債務
對任何已投入實用的項目(也就是說,有客戶在實用產品),不管是要修復缺陷,仍是要添加新功能,總有必須修改產品的時候。在那點上,會面臨2個可能選擇:花合適時間「一次作對」,或者取巧走「捷徑」,爭取儘快推出修改過的產品。
做爲架構師必須決定怎麼作纔有意義。
8八、不要急於求解
架構師多半是開發人員出身。開發人員的主要職責是解決編程問題。相比架構問題編程問題的範圍更狹窄。不少編程問題是很小但比較棘手的算法問題。
架構師和開發人員所以學會了迅速進入問題解決模式,但有時候沒有解決方案纔是最好的而解決方案。許多問題根本不須要解決,看似問題是由於咱們只關注表面症狀。
學會審視問題自己。
看看可否改變問題。
咱們必須戒除「問題解決迷戀症」。
8九、打造上手的系統
咱們十工具的製造者。咱們製造的系統,必定要可以幫助人們——一般是其餘人——作事,不然就是去了存在的意義,咱們也將沒法從中獲取報酬。
用戶體驗應該是「上手的"。
90、找到並留住富有激情的問題解決者
組建一支匯聚優秀開發人員的團隊,是確保軟件項目成功很是重要的事情之一。一旦建成便竭力維護。
提放批評過分。批評過分,可能會扼殺開發人員的創造力,下降其生產力。更糟糕的是,可能會在團隊內部形成紛爭。
以正確的方式經營開發團隊,其重要性不言而喻。
---------------------
9一、軟件並不是真實存在
軟件工程常常被拿去和完善的傳統學科——如土木工程——進行對比。這些類比有個問題,和這些傳統實踐製造的有形產品不一樣,軟件並不是真實的存在。
業務和軟件都是活生生、會變化的實體。業務需求可能會因新近收購的業務夥伴和營銷戰略而迅速變化。
業務需求極可能會發生變化,由於咱們構建的產品是柔韌的。
記住,需求文檔不是藍圖,軟件並不是真實存在。咱們創造的虛擬物比實體物更易於改變。
9二、學習新語言
架構師必須讓別人能理解你。
業務人員專業用語和程序員專業用語是有差異的。架構師須要掌握各個溝通團隊的語言。
9三、沒有永不過期的解決方案
今天的解決方案會成爲明天的問題。
今天作出的選擇,在將來很大程度上是錯誤的。
「分析癱瘓」是今天架構師們碰到的問題之一,此問題最大的歸因,是試圖去猜想對將來而言最好的技術。
9四、用戶接受度問題
人們並不老是滿心歡喜地接受新系統或系統的重大升級。這種情勢,可能會對項目的成功構成威脅。
架構師的目標,是要去了解和衡量用戶的接受度問題帶來的威脅,並朝着能減輕這些威脅的方向開展工做。
「項目擁戴者」能夠幫助消除用戶接受度問題。這個職位的最佳人選,是能表明用戶或利益相關方的人。
9五、清湯的重要提示
清湯是一種很是清澈的肉湯,上品清湯很是清澈,須要不斷重複的精煉濃縮才能烹出。
設計架構也應當不斷精煉濃縮。
軟件中許多漏洞的需求和缺陷,可最終追溯到含糊籠統的語言描述上。拒絕模凌兩可的廢話。概念須要在加上「老是、永遠、無論任何狀況下」仍然成立。
9六、對最終用戶而言,界面就是系統
糟糕的用戶界面埋沒了太多的好產品,最終用戶經過界面訪問系統。
架構師應該確保,隨着架構變化而變的用戶界面也要可以反應用戶的指望。
不只要讓最經常使用的交互易用,並且要使最終用戶可以從中得到回報。
9七、優秀的軟件不是構建出來的,而是培育出來的
在一開始就要設計龐大的系統幾乎毫無好處可言。
設計儘量小的系統,幫助成功交付,並推進它向宏偉的遠景目標不斷演化。
---------------------
粗略的從後面的十幾個裏面提取出如下幾個方面:
數據:程序的核心就是數據,數據的結構表現出數據的形態,數據可能會隨着架構更新,數據庫也要更新。
文檔:文檔是爲了不反覆思考而存在的,相似於代碼註釋,文檔是對工程的註釋。尤爲是對架構師的每個有可能產生分歧的決策,必須用文檔標明決策緣由。
推遲決定(也有其餘翻譯):是軟件開發模型的策略,這樣有助於收集更多有關決定的信息。
團隊:團隊須要的不是單一的一類人,但須要的一塊兒能合理分配工做並完成工做的一類人。找到好的團隊成員必定盡心維護。
用戶:客戶至上,客戶體驗是架構師最好的簡歷,標誌着軟件的成功與否。
溝通:和業務部門溝通,須要學習業務部門的語言,其中涉及到一些專業詞彙,避免溝通障礙。和客戶溝通明白需求,和程序員溝通....
選擇技術:如何選擇使用的技術,要考慮的事項(如:架構師本人的技術,對於軟件的性能,不一樣架構一塊兒融合等)
性能:相對於功能而言,性能常常被忽略。
——————
---------------------
做者:H100
來源:CSDN
原文:https://blog.csdn.net/u014449046/article/details/49390571
版權聲明:本文爲博主原創文章,轉載請附上博文連接!web