2013年2月27日 星期三

物件導向 基本三式第三式 - 多型 Polymorphism

前置技能 第零式 - 物件第一式 - 封裝第二式 - 繼承





假設有個怪需求 「讓某種動物叫 回傳叫聲」

不知物件導向為何物的人可能這樣寫

這樣能不能跑呢?當然能 而且沒有錯誤

但是顯而易見 這種寫法隱藏著災難性的悲劇

因為客戶都很善變 他可能還養了獨角獸掐里 跟 海綿寶寶

這下switch不完了 而且蠢一點的傢伙還會打錯字 case 個 "掐裡" 之類的 然後 Bug 就像螢火蟲之墓 那樣的悲催





試試這個

WTF...這太神奇了 那陀像屎的 switch 跟他說 估掰

而且傳入參數從原本的 object 變成了 抽象型別 Animal 呼叫 Barking 不再需要轉型

實作 Barking 的細節 則被放在 繼承 Animal 的子類之中

在 LetAnimalBarking 方法中 不必去管這些細節 即是日後他要養火星金星人 這段程式都不需要被修改





我很喜歡用貓狗這個古典說詞做說明 因為很好懂

但是我不喜歡用它來做舉例 因為TMD 誰也不會寫個 貓模組 狗模組 還是只有我沒寫過這種模組?





這個就灑狗血的常見

一些龜毛客戶 要求 每筆紀錄 都要有 建立時間跟人員 修改時亦同

這裡有三張相似的 entity class

表單

帳單

案件

因為欄位各異 所以無可避免的 使用時得分別實作 新增 修改

這裡我只寫了其中一個 我想也沒人想看全部 ~.~

但是如同之前的貓狗怪叫 這樣也隱藏著災難性的悲劇

因為 紀錄 成員ID 跟 時間 的部分 一直在重複

如果類似的表有 N 多張 然後某天 PM 拍拍 SA 肩膀 SA 再拍拍你 跟你說

我們 MemberID 不再記錄在 Session 裡面了 要改

你會笑笑的說 好呀 沒問題

但是 SA 走了之後 你會這樣

因為這 N 多張的表 並不是 全都是你一個人寫的 你知道了 有些人總是 「比較天才」 你很難理解天才寫法

然後你的桌子就有點可憐





你開始向上帝懺會 當初沒有好好上課聽老師的話 學好多型的話 就能避開這次 災難性的悲劇

一個 風騷的 abstract 類

entity class 瘦身了!

新增 修改 的時候 不必考慮 如何紀錄 成員ID 跟 時間 的細節

哪天真的萬不得已 有個特例中的特例 不能用 之前的 LogOnCreate() LogOnEdit() 方法 還能自定義新類 覆寫該方法





這下你可以露出燦爛的微笑 因為你跟老闆說 改掉用 Session 記錄成員 要一周

但是其實你只改了 abstract 類 但這只會是個秘密

2013年2月18日 星期一

峰迴路轉的 Entity Framework 轉型

安特踢浮濫沃克 不接受 .ToString() 等等 非 Common Language Runtime (CLR) 方法



int 轉個簡單的string 要用它提供的專用方法



System.Data.Objects.SqlClient.SqlFunctions.StringConvert((decimal)x.MemberID)



WTF~



http://msdn.microsoft.com/zh-tw/library/system.data.objects.sqlclient.sqlfunctions.aspx

2013年2月2日 星期六

對不齊的 img span - PG出來面對系列

list 項目清單 時常見到



        <ul>
            <li>
                <img src='/images/Jst/Status/online.png'><span>線上</span></li>
            <li>
                <img src='/images/Jst/Status/busy.png'><span>忙碌</span></li>
            <li>
                <img src='/images/Jst/Status/leave.png'><span>離開</span></li>
        </ul>




但是有時候想自訂項目的圖示 於是放入 img 然後就悲劇了





解決方案異常簡單 只要給 img 設定 一行 css 即可


vertical-align: middle;




2013年2月1日 星期五

K.O. 一擊斃殺系列 第一彈 之 knockout template

knockout 是一個 javascript library 幫助我們實現 MVVM 及 Model Binding
簡介及教學輪不到小弟來做 請拜 估狗 & 網路神人
http://knockoutjs.com/index.html
黑大的 knockout 神文章




項目清單 這算是 經常遇到的 有點麻煩兒的 需求
麻煩的點不在於怎麼增減項目 而是有時候這個「項目」有點兒複雜
可能包了很多層 DIV 需要許多樣式 還有些按鈕跟功能
但是他們又是一塊塊 重複的 動態產生的 內容(物件)
用 javascript createElement() 來做的話 雖然效能好

但是顯然有些複雜 參數設定冗長 更別說還有些瀏覽器相容性的隱藏 BOSS
jquery 問世後 藉由 $('<div>lalala~</div>') 的淫威之下 我可以直接由一般的 HTML 語法 來產生物件

但是有時候 沒這麼簡單 還必須給物件綁上一些事件 例如有個 div 裡面有個按鈕 按鈕有個事件

這下又變得複雜起來 而且難以維護及擴充




這裡就來試試 knockout 及我最愛的 template 吧

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/knockout-2.2.1.debug.js"></script>
    <style>
        #myDiv
        {
            background-color: pink;
            border: 1px solid black;
        }

        .myclass
        {
            color: red;
        }
    </style>
</head>
<body>
    <div data-bind="template: { name: 'myTmp', foreach: ItemList }"></div>
</body>
<script id="myTmp" type="text/html">
    <div id="myDiv" class="myclass">
        <span data-bind="text: context"></span>
        <input type="button" name="btn" value="按我吧~" data-bind="click: $parent.ClickMe" />
    </div>
</script>
<script type="text/javascript">

    var ViewModel = {
        ItemList: ko.observableArray(),
        ClickMe: function (item) {
            alert(item.context);
        }
    };

    ko.applyBindings(ViewModel);

    ViewModel.ItemList.push({ context: 'yoo~' });
    ViewModel.ItemList.push({ context: 'noo~' });
    ViewModel.ItemList.push({ context: 'woo~' });
</script>
</html>