天天看點

架構的核心

作者: Richie.Liu

http://riccc.cnblogs.com

轉載請注明原作者名以及文章出處

架構的核心

素描總是先草草幾筆畫出一個輪廓,修改到滿意之後,再進行細節加工。人們看到博物館裡龐大的恐龍化石,雖然無法精确到眼神皮膚,但大體的形狀已經躍然腦海中。

架構也是這樣,但有太多的因素,導緻系統構想非常美好,而細節卻讓人不見天日。在一個新系統開發之初,充斥在架構師眼前的,是漫天的需求、要求、期望,各種各樣可選用的技術、設計實作方案。架構師需要用獨到的眼光對待這些繁雜的細節,從特定的高度把架構的核心輪廓抽出來。

把架構的核心架構提取出來,架構師專注于核心架構的設計、驗證,基于靈活、健壯的核心開發出來的系統才會強大。

資料處理型系統,架構的核心是資料流、伴随着資料流的核心處理模型(也就是業務流程、業務模型)。

例如ERP、MES、SCM等系統,整體上看,資料流最終會形成大大小小的環形,交織在一起,互相影響。如果沒有一個整體清晰的模型,肯定會錯誤百出。就算在一個成熟的系統上,有時候覺得在某一環節,某種類型的單據比較獨立,以為對它做一些特定處理,可以很友善的滿足某個客戶需求,但事後也許發現,這個處理給整體帶來隐患,甚至是客戶無法接受的。

企業應用架構中的資料流、核心處理模型,需要考慮如何映射、實作各種各樣的管理模式、理論。例如MRP的make-to-order、make-to-stock,采購的normal PO/blank PO、JIT、VMI,以及各種程度的混合形式。

系統複雜時,核心模型由各個子系統、子子產品的模型組成一個層級結構。

優秀的模型,不僅對産品架構、開發有重大意義,也能夠快速的幫助客戶分析管理上的不足、業務處理上的漏洞、不合理需求的悖論等。

有一點很重要,很多人認為資料處理型系統各個子產品的基礎資料是輔助性、不重要的。當然,如何将這些資料維護到系統中,對核心模型不重要,但這些資料的結構,一般都根據核心模型來确定。在核心模型細化、定案之前,是不能确定這些資料結構的,否則就出現這些資料結構不是服務于核心模型,而是核心模型到處遷就它們的情況。BatchML、B2MML已經把很多模型标準化,例如Equipment Hierarchy裡提到的Enterprise->Site->Area->Process Cell->Unit,現實中Company、Plant、Storage Location、Purchase Group等如何映射到這個模型中,各種資料流、操作處理、業務管理模式如何在這個模型中進行?作為這類系統的架構師,需要徹底了解這些模型,而不是遷就的運用。

技術型系統,架構的核心往往是一個最關鍵的處理流,常常是某幾種技術的組合使用,或者是某種設計思想的運用。

比如說Eclipse的出現而熱起來的插件式,在SharpDevelop、MonoDevelop中都有運用。OSGI的核心是如何對插件的整個生命周期進行各方面的管理,安裝、加載、提供/請求服務、釋放、解除安裝等,也包括了Service的權限控制、Context定義等,在這些IDE類的産品中,自然的以Command等模式+插件式核心,實作IDE的架構,這就是最核心的東西了。如果Context、Chain of Responsibility解決的比較好,像代碼編輯器、對象浏覽視窗、Solution浏覽視窗、編譯調試指令等,整個系統使用者可見的功能基本都可以看作是挂靠在核心上運作的插件,這樣一來,架構的核心與整個系統功能相比較,就再清晰不過了。Eclipse在這方面運用的非常成功,是以靈活、強大,成為Java社群具有統治地位的IDE。如果SharpDevelop、MonoDevelop的架構能夠做到跟Eclipse一樣,我想大家可能會忘記Visual Studio的存在。

在寫CMS的時候,看過現在的DNN,驚訝的發現它也把插件式思想運用起來了,而我之前一直在使用傳統的模闆+标簽替換的方式思考。打破傳統模式,運用新的設計思想,是很有成就感的挑戰。盡管基于項目周期的原因,我最終選擇的主要還是模闆+标簽替換,但也從它那裡受到了一些啟發,以後有機會改成插件式也不會跟現在的主架構發生沖突。

疊代中架構

一個系統,總會有很多功能是輔助性的,典型的一些是為了提高系統可操作性、分析提示預警等能力,降低操作員工作量等各方面的考慮,而設計的一些功能。這 些輔助性功能可能有一組一組的操作界面或流程,也可能是參雜在主流程中的一些細微操作;可能會衍生出很多附加資料結構,也可能隻是為主資料結構添 加一些可調整性參數,或者隻是從不同的視角去呈現、維護某些主資料結構。

大部分時候,把這些輔助性功能剝離開,才能夠清晰地提取架構的核心。回過頭來,核心架構必須接受整個系統需求的驗證。

在提取架構核心的過程中,被剝離出去的功能粒度,完全取決于架構師的認識和把握,但是整個架構必須是可測試的,我們需要在疊代的過程中不斷的把系統功能特性考慮進來,測試驗證架構,完善架構。

資料處理型系統的架構測試,分為多種情況。目前想到的這類系統的模型,大概有兩種,一是資料模型,例如上面提到過的Equipment Hierarchy等,一種是處理運算型的模型,例如MRP算法等。針對資料模型的測試,是模拟各種業務場景,包括管理方式、生産運作模式、不同的組織結構下的運作模式等等;針對處理運算型模型的測試,是設計各種場景的初始資料,驗證結果的正确性、可行性,模型、流程是否存在漏洞、沖突等。可以想象,在這類系統的開發中,運用領域驅動思想是多麼的适合。

技術型系統的架構測試,基本類似Unit Test。不管是運用某些技術的組合,還是某種設計思想,把核心架構用簡單的代碼表現出來,基于Unit Test對架構進行疊代,周遊系統的Use Case場景,是非常必要的。因為這類系統的失敗,基本都是技術或設計思想沒有掌握透徹,或者是錯誤的選擇,基于Unit Test對架構進行測試,可以及早的發現和規避這些風險。

使用測試驅動的方法提取系統架構的核心,也是一種有效的手段。逐漸、充分的疊代,總是會發現不足,使事物完美。

精細設計 vs 過度設計

精細設計與過度設計之間沒有明顯的分界線,有時候甚至已經接近極端傾向,還是會有很多人用贊賞、崇拜的眼光看待。

這是因為對技術溺愛的天性造成,對待那些高深的技術、設計思想,就像獵犬對待獵物,一旦嗅察到,一定要窮追猛打,直到品嘗美味。這種态度一方面容易造成過度設計,更重要的方面是很容易讓人陷入細節的泥潭,無法自拔,以及忽略領域知識的作用等,這也是現實中很多上司不放心完全放權給架構師的重要原因。作為架構師,固然需要對技術具有深刻的了解和認識,也需要具備架構師的眼光,從全局、整體的角度看問題。

如果能夠比較順利的抓住架構核心,一般不會在精細設計與過度設計之間徘徊。

個人經驗覺得,一切以目前系統業務為主,以架構核心為主,去衡量精細設計與過度設計。

如果某個複雜設計在目前系統裡面可有可無,那就把它去掉。不要在核心架構之外為系統做太多可能這樣、可能那樣的假設,為了太多根本不可能發生的假設,而把系統實作變得異常複雜,喪失系統的清晰度和可維護性,得不償失。良好的系統架構,在架構層面已經保證了足夠的擴充性;對于局部而言,也應當能夠在已有架構之下,因應業務發展的要求而做進一步精細化設計。

有另外一種情況,就是團隊成員的成長,總是需要有實踐的機會,要經受挫折的磨煉,溫室裡面長出的花朵生命力總是脆弱的。對于架構師,在局部提供讓人發揮的空間有一定的必要,這種情況下,架構師對核心架構的把握,作用就更為重要。