這是一篇延續“架構師修煉之路”的中“編碼能力”的一篇擴寫,講述一個架構師是如何看代碼、學習代碼、掌握多門語言和如何寫代碼。
可實作的是架構,空談是概念 So don't tell me the concepts show me the code! “不懂編碼的架構師不是好架構師” 好架構師都是超級代碼控。
代碼是最好的老師
從代碼中學習設計的思想、方法是提升類庫設計能力、印證你所了解的概念與理論這就是架構師看代碼的觀點。
基本準備
一個類庫可能有數千個類上萬個方法,應該如何去看呢? 在看代碼前我們需要進行一些什麼樣的準備呢 ?
- 設計模式 - 最标準的23種設計模式基本上要有一個了解,可能一下子不能了解他們的用法,但一定要記下他們的英文名字和基本的用途,如:Factory, Wrapper (Decorator), Command, Builder等 。
- 語言規範 - 熟讀語言本身的官方編碼規範與命名規則,這是共同的标準,也是從官方得到寫代碼的第一指導。
- 要看懂UML中對類的圖形表示方法(類、接口、抽象類、繼承關系、使用關系)
看代碼的方法
這裡所提供的方法就先以C#作為語言基礎,因為C#有極為規範的的文法規則。.net 的文檔在類庫方面的文檔是最完整也是最易讀的。以.net framework作為起點會是一個很好的練習入口。在開始前我還推薦一下大家需要有一個反編譯工具我用的是.NET Reflector, 用反編譯工具不是讓你去抄代碼(代碼本身是沒有多大價值的,價值的核心在于設計)而是可以更深入地了解到代碼是怎樣實作的。用反編譯工具看微軟的代碼會看到很多的不同的,你會發現大最設計得非常有意思的内部類 (Internal) 。從中大至可以推斷出微軟的開發方法,“在外部接口完全一至的情況下,讓程式員編寫的自由度最大邊界就是内部類與内部方法” 你可以馬上動手先看看 System.Web.Mvc.dll 的實作
要點:多問為什麼,帶着問題看代碼——為什麼這樣寫(存在理由)?為什麼這樣設計(出發點)? 由你來寫又将如何實作?
看命名
以面向對象的語言為例,大多會在名字内帶有具體的用法資訊,從名稱推算可能使用的模式及實作
帶有模式印記的類:
- TagBuilder - 以Builder模式實作的Html标記的建構器
- StringBuilder - 以Builder模式實作的字元串構造建器
- XXXXWriter - 以建構器模式實作的各種寫入器
- ConnectionFactory - 資料庫連接配接對象構造工廠
XXX+模式名 是慣用的對模式類的一種命名規則
找到了模式實作如果你看不懂,那恭喜你這就是學習的機會到了,馬上翻開設計模式與實作類進行對照印證,這個過程可以加速模式在你大腦中的印象與加深了解。(模式是架構師的大殺招,能不能上檔次就看對模式的了解與認識了,一有機會就應該學)
帶有家族印記的類:
XXX+Base - 抽象類
基類名+XXX - 某抽象類的子類
是繼承關系一種常見的命名規則。
注:每一種基礎語言會有自身的命名規則,是以必須對官方提供的命名規則爛熟于胸,既可以學習别人怎麼寫代碼也可以規範自己的代碼寫法。
做完這兩個練習基本上你可以在不看 Classes References(類手冊)的情況下一下子了解一大堆類的存在與用法。
看接口
接口在設計中有着極為重要的地位,結構再複雜的系統到了接口級别基本上都會很簡單。而且也是判定這個類庫設計是否成熟的一種标準。接口與接口間的定義就定義整個系統的基本架構。看接口的最基本意義就是深入了解類庫設計者的設計思路與了解類庫最核心的能力。
這裡我們以 IRepository 為例來講講怎麼去看接口 (如果想深入了解IRepostiory的朋友可以閱讀我之前的文章:“Repository模式與UnitOfWorks模式的運用” )
我以 IRepository 為例是因為它的共識度很大,而實作起來可以很龐大也可以很小,衆所周知IRepository提供的就是對某個實體的CURD(增加、更新、讀取、删除)的一個接口。那麼當我們看到它的存在時,應該可以推斷出另一個接口:IUnitOfWork 因為它們往往會是孿生兄弟般的存在,再進一步推斷是否會存在IRepositoryFactory 和 IUnitOfWorkBuilder 呢? 那麼就可以帶着這些問題在類庫中找答案。
通過IRepository我會可能會發現一大堆的Repository類,
如抽象類:EntityRepositoryBase, FiledRepositoryBase ,JSONRepositoryBase 等
具體類:BlogRepository, PostRepository, UserRepository 等
注:作為練習大家可以去下載下傳我在NuGet上釋出的一個名為 DotNetAge Document Storage 類庫,裡面就有Repository的實作
一但掌握了從接口看結構的方法,就可以快速地在無文檔的情況下了解類庫的核心與設計理念。
參考“最佳實踐”
一般上來說,流行的語言都會提供官方的“最佳實踐”提供下載下傳學習。這是一個必修項目,同一個需求,我們可以采用各種的設計方法來實作,但哪一種最好的? “最佳實踐”就提供了方法選擇的指導。“最佳實踐”會有大量文檔輔助講解,在此時使用上述兩個方法去學習那将會更大地提高你在設計上的提升。
随着不斷的積累與大量的代碼閱曆,你可能就會得到這樣一種能力:随便拿個Dll,在一個短時間内你可以如數家珍般說出整個Dll中的特點與功能。
這,就是“看”的練習方法,與練習後的效果
學
要成為架構師就需要突破語言的障壁,不同的語言有不同的優勢,設計應該是因勢利導,好的架構可用任何語言實作,反過來優秀的架構則應盡可能地發揮語言的特性。應用此方法前首先你至少已掌握或精通一門語言。
學習多種語言的動機
- 開拓視野,從不同語言中學習特有的設計理念
- 尋找與更新自己的 “最佳實踐”
- 規避語言被淘汰的風險
開拓視野
我最近在不少網站上看到這樣的一種論調:“學語言隻學一門就好,不需要多隻需要精”。咋一看,似乎是對的,而我認為僅限于初學者或不求進取者。這是一種語言同質論,是一種誤導與限制!如果學習語言能“窺一斑而見全豹”那就不需要有那麼多的其它語言存在了,對嗎?
當對某一門語言精通(我指的是精通類庫而不是文法)後,這個時間大概也得幾年,很容易進入到一種“思維定式”,以某種固定語言為基點想問題,或是設計。一旦進入這種狀态也就意味着局限性的出現,程式員或是架構師就被限制在了一個局部的小範圍,而且還是風險極高的範圍内。
IT的發展是飛速的,今天的寵兒明天的乞丐這種劇目屢屢上演着,你願意被大浪淘沙嗎?吊在一顆樹上真是一條死路,這是技術發展的風險層面。又,你的設計工作對你還有挑戰性嗎?你是否仍然對設計和開發充滿激情?你的設計是否在當下可以有什麼讓你自豪的特色或建立呢? 被同質化後這些答案都會被否定掉。
我的論點是:不斷學習各種語言,體驗各種語言所帶來的開發與設計的激情,開拓自我的視野才是一個架構師應走的路。架構師不單單是技術的選擇者,而更應該是技術的整合者。
選擇“最佳實踐”
我們長期會在某一領域内工作,自然而然會誕生出對此領域内的軟體的設計理念與實作方法。但這僅是一種,舉一個最簡單的例子,同一個網站我們可以用ASP.NET MVC , Java, PHP 或是NodeJS來實作,固然實作方法與代碼量就截然不同了。随便寫個部落格網站就能體驗他們的差別所在:
- ASP.NET 和 Java的思維方式與代碼量差異不大,學習曲線最長、 Hosting 資源成本中等,但資料庫Hosting成本高
- Php 相對前兩者簡單而且資源衆多,Hosting 資源最多,成本最低
- NodeJS性能最高、學習曲線最短、代碼量最少、資源也最多但Hosting 成本最高
從這個比較中可見,作為架構師不單要考慮設計方法與實作,還得考慮部署環境。如果隻是某一方面的“能手”那隻能幹瞪眼,無可選擇。
我不是要選擇“最好”的而是要選擇“最合适”的,因時制宜,因地制宜才是我們所需要的“最佳實踐”
成為 “O” 型架構師
開發是一個團隊共同完成的,與真實社會一樣,活在哪裡就說哪裡的話才會深入了解對方的文化。 架構師不是一個獨立的個體,而是團隊中不可或缺的成員,在行政與地位上與其它成員是對等的。開發隊團就像是一個人,流着共同的血液。一個架構師,一份設計就應該是一種“O”型血,無論在哪個隊團内都能融合,使用哪種語言都能實作與優化這才是一個好架構師的目标。
學習多種語言的方法
學習語言的方法大家都會有各自的路徑與方法,在這裡我隻是介紹一下我自己的學習方法僅供大家參考與給我建議。我從業也10多年了,經曆了不少語言以下這些是一些記憶與狀态:
- Delphi (1-5) (Object pascal) - 這是初戀 , 擁有最多的界面元件和最簡單的可視化開發環境,VCL算是當時最好的選擇。
- VB (2-6) - 最容易調用COM的語言也是做面向對象很苦B的一個了。
- C++ - 學得最差的
- java - 用來學面向對象的
- C# - 算是我最擅長的,也是做項目最多的
- Php - 隻能算是懂一點
- javascript - 我最喜歡的動态弱類型語言。
- css/less - 最讓我頭疼 (有了Less會好一點)
- html/xml/xslt - 最容易建立方法論的标記性語言是最容易建立發散性思維與抽象思維的工具
- Objective-C 和 Swift - 現在在學的
每一種語言就像自己的女朋友一般天天在身邊陪伴着我們,是以想學得快首先是愛上她。即使她不再受寵也她會給我們留下很多美好的記憶。
感性認知
我學語言的第一步是不看文法的,因為面向對象的語言文法上基本是相似的,而且文法參考會很長讀起來慢(這跟找老婆不要光看外貌是一個理)。我是從類庫入手的,從主打的類庫中可基本上快速了解整個語言的重要特色和常用的内容。就如iOS吧,一入手我會先看Cococa Layer中的UIKit,花兩小時看完就知道XCode怎麼用了然後就可以做個簡單的移動應用跑一下,從感性上互相認識一下。
互相印證
沒有哪個語言是沒有參照物憑空發明出來的,就像學java時如果學過c++會很快因為java就是在極大層面上改進C++而來的,學C#的時候學過java就一下能上手,因為C#是微軟沒買到java自己搞出來的同時也去改進了java。是以語言之間會有互通性存在,在學習的路徑上可以先了前他們的前輩是誰,有什麼特色通過雙向的印證了解可以很快速地去掌握與深入了解一門語言。
長年的積累
掌握一門文法很快,精通一門語言就是硬功了。這和我們學自然語言一樣,詞彙量是日積月累的成果。開發語言的詞彙量就在于類庫了,每一門語言的标準類庫也是夠我們喝一壺的,需要實踐、學習與了解結合經驗沉澱成我們的成果。在這方面我給出的建議就是要培養自己的耐心與毅力,羅馬不是一天建成的,高手也不是一天就能修煉出來的。除了掌握官方類庫還得将業界流行的類庫和架構都能了解與熟悉這才算是“精通”。
寫 - 瘋狂的編碼
“實踐是檢驗真理的唯一标準” 能說不如能寫。學到的知識是别人看不到的内容,作為程式員或是架構師将腦中的精華程式化呈現,然後成為産品這才是我們的終極目标。
學會一門語言并不代表寫得好,作為一名架構師寫的代碼要求更是不同:
- 易讀 - 命名是否符合代碼規範,所有接口是否全部代碼都有注釋
- 易用 - 每一個類,每一個方法都是架構師與程式員的UI,少參數,容易了解的設計可以大大減少溝通成本。
- 架構化 - 一個一個類寫是很慢的事,要活用模式于代碼中能同時建構出10幾個或幾十個類。
- 參考性 - 架構師不是程式員,寫代碼為的是固定核心功能與公共用法,便于成員開發。面對複雜的場景需要多寫示例同時也是測試設計的易用性的方法。
怎麼才能達到這樣的标準呢?
- 為自己立項從現在起為自己而編碼
- 多寫代碼片 - 對局部的理論進行實踐,多寫一些小的代碼片段或實驗程式,而按正式項目一樣來對待。完整的記錄,共享源碼獲得Feedback,有良好的注釋。
- 模仿是學習與了解新事物的最佳捷徑 — 可以去仿造某些項目,當深入其中可以更直接地了解設計者的最初設計想法,同時也可以得到一個仿造品(不是抄,仿造的目的是獲得編碼經驗)
- 嘗試使用模式并控制類的規模
最後也就是時間的積累,瘋狂地編碼。同樣的時間一個架構師的編碼能力至少需要同等于五個以上程式員同時編碼。
小結
架構師之路是一條很漫長而且需要不斷學習、思考與實踐積累的道路。我隻是走了這條路的一小段,以此總結與更多的朋友分享共勉。在下一篇文章中我将會從另一個角度來談架構師的修改項目:表達力。希望有興趣的朋友能給予更多的關注與回報。