好事要做到底,我們需要full stack的設計

http://www.blogjava.net/OneEyeWolf/archive/2008/01/01/171990.html

 

full-stack 的設計,意味着各層能夠無縫的集成在一起,遵循的DIY原則(don't repeat yourself),將各層共用的東西,抽取出來,並通過自頂向下的設計,無縫的集成在一起,粘合在一起,達到更高層次、更粗粒度的重用,同時爲了保證靈活的可擴展性,在更高、更粗的粒度上遵守開放-封閉的原則,在各層的各個關鍵點,要提供諸多的鉤子,回調的接口,供使用者擴展。full-stack的設計,在層與層之間,並不一味的追求鬆散的機制,而是相反,在層與層之間增強一定的內聚性,粘合力,以此來達到粗粒度的封裝與重用。

  可以說full-stack 的設計,其爆發出的威力是巨大的,相對普通的單一層面的設計,在開發效率上不是一個層次上的,基於28原理的設計,可以滿足80的調用者直接開發,19%的調用者,通過擴展點進行擴展來滿足需求,對於1%鑽角尖的需求,自己去造輪子。

  spring, ruby on rails, Zend都是這樣的工業級強度的full-stack的設計,我們的設計如果以他們爲中心,生產力得到了極大的提高。

  但是我現在厭倦了,屁大的事,就要裝模做樣的寫一個DAO,寫一個Service,寫一個Action,再寫一個JSP,八股文式的開發模式,味同嚼蠟。我們的代碼仍然在急速的膨脹了,我們仍然感覺很累,我們的千行代碼出錯率仍然沒有減小,這不是個好事情。

  有人說,這就是設計嗎,這連頭豬都會。

  我做了電子商務網站多年了,無論是管理還是技術,都非常的有挑戰性。

  從用戶角度,前有看不見摸不着、挑剔的、脾氣暴躁的互聯網用戶,後有工作量巨大、業務繁忙的後臺業務部門用戶,他們狠不得,用魔法棒,一指,網站上就會有這個功能,時間不等人。

  可是電子商務網站角度來講,不同於一般的內容門戶網站,出個錯沒有什麼大不了的,當用戶在我們的網站上看到的一切東西都是有法律效力的,當用戶下單成功交易的一瞬間,這種關係已經實施,出個錯,誰也擔當不起,大家不記得DELL門事件,網上直銷價格報錯了,引出了多大麻煩,在外面,有公司擔當着,在公司內部,估計當事人,也是痛苦的不得了。 

  我們即要追求快速開發,以用戶爲中心,擁包變化,又要保證工業級的強度的穩定。

  一般的發包,從需求收集,明確,整理,發佈release計劃,拉分支,開發,內部測試,提交功能測試,壓力測試,on stage, on production,上線跟蹤測試, 合併分支, 這樣的流程,一個環節都不能少,不能出漏子(當然只是從理論上保證)。
   這樣即使一個月發一個包,開發時間不過10多天左右,這樣的發包速度,還是滿足不了要求。當我們對他們說,這個功能,下個月才能上線,用戶會無辜的睜大雙眼,看着你。
   所以在設計這個層面上,我們需要更多的重用,更多的粗粒度的,工業強度更強的重用,可以更高層次的在大大提高我們的開發生產力同時,減小我們出錯的概率,當你的程序出錯的時候,你一般不會就認爲是springe的BUG造成的吧,是自己的代碼出錯。 

   我們不需要供養着一批只是評審工具的、滿嘴術語、動不動就用可用性、可擴展性之類的Matrix表格讓我們看他們的評估結果的架構師。

   我們也不需要滿口hign-performance、large-scale、羣集、ajax,光說不練的傢伙,對於一個成熟的電子商務網站來說,基於Scalability的架構已經趨於穩定,並有專有團隊來維護,用不着你來天天搞羣集。

   我們也不需要只會寫個JAVA類的所謂的設計師。 

   我們需要的是full-stack的設計,我們需要的設計師,對於互聯網應用來說,三層都應當相對精通,就像習武之人,任督二脈都打通那種高手,纔是NB的高手,從front到database,都有要豐富的經驗。

   我們需要的是基礎紮實的,有熱忱的設計師,能夠真正的幫助開發人員解決問題,提高生產力,而不是那種只提供約束、規範,不提供方法,不解決問題的人。 

   full-stack設計體現的是一種設計思想,是要在不管是微觀還是宏觀層面上,去應用這種思想,並不是要一定要設計出像spring那樣大的東東來,也不可能。 

   我以一個電子商務系統當中的業務基礎數據字典子模塊的設計(很多人都做過,可以做一個對照),在一個三層切面,論述一下full-stack的設計的具體應用:  

1.抽象描述層需求

(1)表現形式:下拉框、單選框,多選框,列表框,表格,文字
    不同的數據有不同的展現形式,  同一數據在不同的頁面,也有不同的表現形式
    例如:我們在旅遊網站上看到的,有的網站在選擇城市時,是下拉框選擇的,有的是彈出窗口,並將所有的城市按表格的形式列出來的, 還有的就是列表框顯示的

    對於多選框,一般都需要自動添加一個全選的checkbox,並生成全選事件,不要調用者自己再寫。
    如果是下拉框,要能夠自動添加一個“請選擇”的option或者從傳參數中指定一個header. 

    默認選中值,當傳入默認值時,能夠設置默認選中。

(2) 控件事件模式
  要能夠提供Callback,如Listener、Observerable模式的事件注入。 

(3)基礎數據在頁面上的佈局方案,
   基礎數據是放在Table的TD單元當中,還是DIV當中
   對於多選框的展現與佈局,當多選框多的時候,使用表格來佈局,來保證換行時,自動對齊。

(4) 數據轉換與渲染

   在頁面上,能夠將ID值,轉換成用戶可讀的文字值,如訂單狀態1轉換成已成交,2已配送,3,已取消的形式。 

(5) 前後臺數據交換機制:

    你可以使用異步應用,如ajax來解決問題,也可以使用同步的如JSP標籤來解決問題。

    基於ajax的前後端數據交換格式:XML, JSON, DWR, 自定義等等。
   作爲你自己的單獨的應用,沒有必要這麼花哨,無論那一種,都可以。但如果是作爲開源的、或者是商業產品,給未知的應用調用,就要考慮可擴展性,讓調用者可以擴展,使用自己熟悉的方式,如EXT提供了XML,JSON都多種reader,你也可以擴展與DWR集成。 

2.抽像後臺需求

(1)多數據源的屏蔽:XML文件配置、properties配置、本地數據庫表、遠程Webservice接口。

    如果是基於頁面指定的查詢條件,動態查詢的接口,如類似於ibatis的查詢接口

    List ds.queryForList(queryID, paramMap)   
  

(2)排序

   a、不同的基礎數據在頁面顯示時,有不同的排序需求

      如城市是按拼音排序的,
      訂單操作步驟數據是按序列號來排序的
      沒有要求的,默認是按錄入順序來排序的  

   b、排序即可能在後臺排序,也可能在頁面上基於javascript排序
   所以無論是在前端,還是在後臺,都要提供一個倒鉤接口,讓調用者可以按自己的要求對數據進行排序。 

(3)分佈式環境的要求
    分佈式在中大型的電子商務當中,幾乎是必須的,作爲底層的支持,爲其它分佈在不同服務機器上的應用都要提供共用的的基礎數據,同時要緩存,當數據修改後,要刷新緩存,並要通知第三方的應用。如機票、酒店、自由行、呼叫中心、配送、結算中心等等十幾個子系統應用都要調用城市、支付網關列表等數據。

(4) 數據管理
  添加、修改、刪除基礎數據的權限.
  數據排序處理。

(5) 緩存
  緩存是一定要有的,一個是數據中心的緩存,當遠程調用者又在本地做緩存時,數據變化時就要提供遠程通知的接口,否則調用者客戶羰的數據就不會自動刷新。

  緩存,可以基於spring+EHCache,配置緩存方案和策略。也可以通過適配器外接到其它的緩存配置方案上。

設計實施:

BasicData.config:{

    type:'select',//*下拉框、單選框,多選框,列表框,  文字, tbody

    id: 'select_id', //*指定綁定的控件ID,如果ID不存在,則系統會創建指定類型的控件,否則就綁定

    name:'city',//控件名稱,不是必須的

    parentID:'div_city', //*父類容器ID,如果容器ID是tbody,則數據會自動填充到表格當中

    defaultValue:'1,2,3', //默認值,對於多選框,多個默認值時有逗號隔開

    resourceId:'', //*傳給後臺的基礎數據標識,根據此代碼,可以獲取到指定的基礎數據,如送票城市、轉賬銀行等。

    autoCreaeSelectAll:'y', //是否自動生成全選 

    header:'請選擇',//如果是下拉框或列表框,要生成一個header

    event:{name:'onchange', event:'changeChild'}, //事件監聽

    comparator:'compare',//排序比較函數,

    cssStyle:'', //CSS風格

    paramMap:{} //用於後臺動態查詢的查詢參數

    datasource:ds//設置數據源,可以爲空,系統自動使用默認

}

 

調用者:

 /**

 *獲取信用卡列表,進行復選框排列

 *@divID 你設置的DIV的ID號或其它父控件ID

 *@paramName 控件名稱

 */
function setCreditCardList(divID_, paramName_, defaultValue_) {

    xBaseData.draw({type:'select', id:paramName_, name:paramName_, parentID:divID_, dfaultValue:defaultValue_});
}

 

整個方案實施的效果
  1.幾乎是一勞永逸的解決了基礎數據的需求問題
  2.開放者只需要在頁面,一行JS代碼或一行標籤,就解決了問題,不用關心其它的東西了。
  3.使用者已經忘卻以往的諸多不便,對一個局部的編碼者而言,變化是小的,對於設計者,從全局幾十個子系統,上百名開發者而言,效率的提升是顯著的。所以設計者的格局要大。

  4.關於基礎數據出錯的概率,當然減小了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章