2014年4月29日 星期二

ASP.NET Web Form 對應優先設計 (Mapping-First Design) 第一彈 - 提線木偶

如果你沒聽過什麼 對應優先設計 (Mapping-First Design) 的話

先別急著 估狗 偽基 因為...

這名詞 是我掰的 :P





It was long long ago...

那個時代 還沒有 ASP.NET MVC (或者有只是無人問津)

拉控項 Click 事件 寫 CODE 天經地義

一個 Click 事件 幾千行 CODE 家常便飯





過了一陣子 開始流行 3-tier n-tier

主要把 程式分成 表現層 邏輯層 資料存取層 封裝起來 降低耦合程度 增加可維護性

但是老實說 控制項 跟這些架構什麼的 相性 很差

很多時候 要額外寫一堆轉換的代碼

像是...

參數接控制項屬性

string name = TextBox1.Text;

控制項屬性接參數

TextBox1.Text = name;

當然 "絕不會" 只有一點點參數 跟 固定種類的控制項

當 TextBox CheckBox RadioButton DropDownList 參在一起做成撒尿牛丸

資料庫欄位 跟你玩 85度C ( c = column )

這時候...

真嗣表示:這時候,只要笑就可以了





但是這煩惱其實沒有困擾多久 因為後來 ASP.NET MVC 出現了

Model-First~

Model Binding~

ORM~

各種風騷技術

一開始自然覺得很硬 各種約束 奔放不起來

但是玩久了之後 發現就那麼回事而已

招式套路 基本會用上的就那幾招

控制項 神馬的 不用鳥他 潮爽der~

View 自由發揮就好了





因緣際會之下 又回來玩了一下 Web Form

之前的問題又回來困擾著我

但是意外發現 .NET 4.5 Web Form 竟然也吃 Model Binding 跟 Routing

傳說中的 瘟疫同化???





但是 4.0 或 之前的 專案 仍然無解 (誰也不敢貿然升等)

於是就想 那就自幹吧 寫個小元件來搞定他

試過很多奇奇怪怪的方式 最後都覺得不好

感覺上就是 寫了一些 偽 Model Binding 的類別

要搞 Model 何不直接用 MVC?

要搞 Model Binding 何不直接用 .NET 寫好的?

搞這些花招 又不能直接輸出到頁面上 就算真的可以直接輸出到頁面上的話 控制項又要幹嘛?

取值 轉物件 運算 塞值回去 繞一圈 這樣真的比較有意義?

想了許久...還是沒有滿意的做法





直到某天我看到小溪裡的小魚逆流而上

我頓時領悟到 根本不需要 Model 呀

寫多了 MVC 習慣用 MVC 來思考 自然怎樣都像在抄 MVC

回歸本質來想想 問題跟需求到底是什麼

首先 邏輯層 資料存取層 這兩層 沒什麼大困擾

不管是 Web Form 還是 MVC 都只是一些 物件導向的把戲

頂多差在 資料存取

Web Form 通常用 ADO.NET 搞

MVC 通常用 ORM 搞

問題還是在 表現層

MVC 靠 Model Binding 進 controller 的時候 就有現成的 Model

然後 資料存取也能沿用這些 Model 一氣呵成

但是 ADO.NET 在操作的時候 並沒有一定要使用 具體型別(Model)的要求

SqlParameter 只要給他 名稱 跟 值 就能用了 (保險點再給個 SqlDbType)

把 input 轉成 POCO 再給各層使用 在 web form 裡面的意義並不大 尤其只用 ADO.NET 來資料存取

(Plain-old CLR Object) 永續儲存無知物件 <= 中譯超有梗

只要想辦法處裡 "對應" 就好了

設法紀錄 控制項 跟 資料庫欄位的對應關係 之後就可以依靠對應關係來交流





不靠 Model 屬性名稱來做對應的時候...

Dictionary<TKey, TValue> 是你的好基友

Value 用 object 就好了 但是重點是 Key 該用什麼?

string 怕打錯 int 怕太抽象...(這些都是魔術化參數)

別忘了我們的 好碰友 列舉!! (列舉又能變 string 又能變 int)

先標記好欄位名稱當 KEY

然後老梗 拉控制項 先全用 TextBox 試水溫

再來 設計一個 ValueMap 物件 用來記錄 Key 跟 控制項 的對應關係

還有最主要的 GetlValue SetValue 方法

這邊稍微解釋一下

Func<T> OnGetValue 跟 Action<T> OnSetValue 是用來處理自定義的 取/設 值 的方式

否則預設的情況下 取/設 值 針對慣用的屬性

TextBox.Text

DropDownList.SelectedValue

RadioButton.Checked

CheckBox.Checked





有了 ValueMap 之外 還需要一個專們來操作 ValueMap 集合的 物件

這裡的 Buster 是指終結者 :p

然後就是來使用它

SetUpValueMaps 可以使用 partial class 的方式 包在另一頁 會乾淨一些 當然 見仁見智

最後就剩 Click 事件裡的東東啦

通常各家都有祖傳私釀的 SqlHelper 來玩 ADO.NET 或者用 enterprise library 也 OK

因為 參數吃 DataRow 跟 SqlParameter 要怎麼變出來 都無所謂

現在只剩兩行...

實際功能 DEMO 則不值一提 就是 查詢 / 更新 顯示在 TextBox 上面

但是樸素的外表又豈能看出 Click 事件 裡面竟然不需要碰到 噁心的控制項 這種美麗內在呢?





咦?如果我 TextBox 亂打 不合型別會怎樣?

呵呵呵 當然是會壞掉呀 因為現在還沒 實作欄位驗證

敬待 下回分曉 ˊ_>ˋ





標題梗:

沒有留言:

張貼留言