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