简单干净的C#方法设计案例:SFCUI.AjaxLoadPage()之二
?
合并顯而易見的代碼
所謂顯而易見的代碼,就是看上去和別處相同的代碼。
在這個例子中,就是View‘中初始頁面顯示的內(nèi)容與未來刷新的內(nèi)容重復(fù);Controller中初始顯示的運(yùn)算和刷新的相同。
Controller好辦,如此:
而cshtml頁面中,只需要添加一個在頁面初始化時自動刷新的函數(shù),就能把<div id = "leftpad">變成空的,由刷新頁面來填充。代碼變成:
$(document).ready是多出來的代碼,負(fù)責(zé)第一次初始化時填充<div id = "leftpad>的內(nèi)容。
封裝多余的技術(shù)代碼
何為多余的技術(shù)代碼?之前在AjaxValue系列中曾經(jīng)提到過接口封裝的兩個原則:
最小信息原則:方法接口應(yīng)只傳遞最必須的業(yè)務(wù)信息。
包括兩個層面:
1. 技術(shù)數(shù)據(jù)不要傳遞
2. 業(yè)務(wù)數(shù)據(jù)不能重復(fù)
?
現(xiàn)在,先從業(yè)務(wù)角度分析,這個函數(shù)接口設(shè)計(jì)中,到底哪些信息是必須的;讓我們來用這一原則,把上面最后的一段cshtml代碼,變成一行代碼。
1. 如果要刷新,應(yīng)該調(diào)用什么函數(shù)(一般是一個JS函數(shù),提供給左邊的紅框,紅框運(yùn)行成功,就調(diào)用這個JS函數(shù))
2. 用于刷新頁面的Ajax Url(上述JS函數(shù)被調(diào)用后,應(yīng)該到哪個Url獲取刷新內(nèi)容)
3. 刷新成功后,要繼續(xù)執(zhí)行什么操作(另外一個JS函數(shù),比如刷新的內(nèi)容“錯過了document.Ready”要重新套用一下——嘗試了live功能,不知道為什么無效;或者要串聯(lián)刷新多個區(qū)域,本例中沒有)
沒了(后面還會看到一些,不過是為了別的功能)。有幾個東西是多余的:
1. $(document).ready.....,因?yàn)槊總€AjaxPageLoad都執(zhí)行,所以是固定的,不用作為參數(shù)傳入接口。
2. function refreshLeft() ...{ $"#refreshLeft")....,因?yàn)檫@個按鈕是多余的,并不需要人手去點(diǎn)擊,只是函數(shù)實(shí)現(xiàn)中的一個步驟而已。換言之這個按鈕叫什么都無所謂,只要ready / function / SFCUI.Link(id: ...)中出現(xiàn)的值相同就行,無需人工指定。
3. <div id = "leftpad"></div>也是多余的!因?yàn)榧热辉谶@里寫下那一行代碼,就在代碼處LoadPage,至于Load到什么東西里邊,ID叫什么,都無所謂。
所以,接口調(diào)用應(yīng)該是:
這句話是一個helper,將負(fù)責(zé)生產(chǎn)前面代碼中提到的<script>及其中的兩個函數(shù)ready和refreshLeft、中間的<div>@SFCUI.Link中的Ajax調(diào)用</div>、最后的<div id = "leftpad">
下面是Helper的源代碼,里邊多了一些參數(shù),最后解釋:
1. 先看突然跳出來的int id = _rand.next()
之前提到,我們有很多“隨便”的變量,比如那個"refreshLeft",叫什么都行,外界不關(guān)心。但是如果設(shè)為常數(shù),則如果在同一個頁面上放兩個LoadPage的時候,會打架,所以用個Random生成ID。為什么用static 的呢?因?yàn)镽andom的生成機(jī)制,是利用調(diào)用時的系統(tǒng)時間作為“種子”,從種子產(chǎn)生下一個隨機(jī)數(shù)。如果調(diào)用時間間隔為“0”,就會產(chǎn)生出相同的種子進(jìn)而相同的隨機(jī)數(shù)。static就沒有這個問題了,大家用一個,順著排。
總之,隨機(jī)的id代替了"refreshLeft"這個本來需要傳進(jìn)來的“變量”。
2. TagBuilder script則直接在代碼上方產(chǎn)生一段script,免去了編寫script的工作。
為什么要判斷refreshFunction為NULL的情況呢?因?yàn)橛幸环N場景不會重復(fù)刷新。
在我的項(xiàng)目中,菜單極其復(fù)雜,產(chǎn)生菜單的時間,甚至比頁面本身都長。但我們也不像犧牲強(qiáng)大的菜單換取性能,怎么辦呢?子菜單延時產(chǎn)生!
由于人們在頁面出現(xiàn)后的1~5秒內(nèi)都不會操作菜單(要離開這個頁面時才會操作),所以我們設(shè)置所有繁重的子菜單都使用AjaxLoadPage加載,而且注意最后一個參數(shù)timeout,它們多數(shù)在1000毫秒后才加載,那時候頁面早就爽快地展示在用戶面前了。
這種場景,不會有人刷新菜單了,所以就不用RefreshFunction這個參數(shù)。
3. TagBuilder pageContainer 代替了原來最后的<div id = "leftpad">,它的id也是隨機(jī)生成的,但是由于1、2、3中保持了id的互相照應(yīng),雖然外界看不到,但是內(nèi)部卻順暢運(yùn)行。
4. 最后多了個style,是我們加載菜單時的需要,這里就不多說了。
尾聲
合并顯而易見的代碼是初級程序員的基本功,也是產(chǎn)品代碼的基本要求;封裝多余的技術(shù)代碼難度較大,但是只要用心,上述提到的原則也沒有做不到的。
為什么要費(fèi)勁封裝呢?散裝的代碼對程序員要求低,只要好好測試,功能相同,也不會出現(xiàn)缺陷,不也一樣嗎?
在16年的IT從業(yè)中我發(fā)現(xiàn),所有最后開發(fā)面臨崩潰的軟件,很少有受到單個技術(shù)難題或缺陷困擾的,多數(shù)都百病纏身;而百病纏身的主要問題,是可維護(hù)性差;而可維護(hù)性差的主要原因,是代碼臃腫重復(fù),尤其是似重復(fù)而不重復(fù)。
封裝后,則:
1. 總是使用同一段代碼,易于維護(hù)。
2. 總是重復(fù)使用,代碼的質(zhì)量有保障。
3. 一個地方發(fā)現(xiàn)缺陷,修改代碼后可以同時避免多個地方的缺陷。
4. 在無需深入到技術(shù)層面的時候,可以方便地在業(yè)務(wù)層面閱讀代碼。
5. 把時間花費(fèi)在深究代碼的封裝上,比重復(fù)碼字要有趣得多。
……
在之前的IT職業(yè)生涯的“危險職業(yè)”系列中有很多人提到:“我一直在做重復(fù)勞動,沒有積累,是不是很危險?怎么辦?”其實(shí)萬事萬物看似重復(fù),其實(shí)不重復(fù)。本人從事Web編程只有一年多(其中只有6個月的編程量超過總工作量的50%),Jquery上上個月剛大致弄明白,但是我相信很多Web編程很久的程序員都不會封裝這些代碼的,而是“重復(fù)地”拷貝粘貼代碼。
所以實(shí)際上,沒有重復(fù)的工作,只有重復(fù)的工作心態(tài)。
之后我會寫一篇關(guān)于“重復(fù)勞動中如何提高”的IT職業(yè)生涯系列文章。?
本文轉(zhuǎn)自火星人陳勇 51CTO博客,原文鏈接:http://blog.51cto.com/cheny/1101508
總結(jié)
以上是生活随笔為你收集整理的简单干净的C#方法设计案例:SFCUI.AjaxLoadPage()之二的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rsync 服务与配置文档
- 下一篇: 启动CLR