前言
最近一談起程式設計,總是離不開「物件導向」而一般入門的程式教學書籍也是一直強調「物件導向」的重要性。雖然強調歸強調,但是一提起什麼是【物件】總是會用一台汽車(更甚的是,也有用一架飛機的)來做比喻,而事實上我們所寫的程式永遠也不會遇到一台汽車,所以總是很難將【物件】跟我們的程式聯想在一起,也很難將【物件】的思維運用在程式設計上。
阿源哥哥,一向喜歡用切身有關的例子來講解所要表達的觀念,而且喜歡把複雜的理論簡單化(甚至簡單到讓人覺得,這也沒什麼)。相信有在工作的人都有領過薪水吧!就算沒領過薪水應該也能體會到,該怎麼樣才算能領到一筆薪水。而最近阿源哥哥正好完成一套「薪資管理系統」,因此會以這個來表達一些物件的概念。
就像前面所提的,這篇文章只是想表達【概念】,而概念是跟將來實作時所使用的程式語言(C#、VB.NET、C++、Fortran‥‥),使用者介面(WinFrom、WebForm、WPF、Silverlight‥‥)無關的,但是總是要有圖、有虛擬程式碼,才方便講解,所以文章會用完成「薪資管理系統」恰巧所使用的VB.NET、Windows Form的文字圖例來表達。
一個物件

如上圖所示(圖只是為了方便解說,此時應該是沒有物件長相的概念,且該物件也不見得一定長得這樣),讀者應該不難理解,要想領到公司的薪水(一天的薪水),必要條件就是依規定的上下班時間來上下班,符合條件後就計算出基數,成為計算薪水的基準。
因此,我們可以將一個員工某天的應上下班、實際上下班,及判定結果‥‥,當成一個物件,而「日期」「應上班時間」‥‥‥「備註」等可稱為,用來形容一筆出勤記錄的【屬性】。
物件集合(也是一個物件)


一個員工整個月的「出勤記錄」集合起來,就是一個「月出勤記錄」的物件了。而某日的異常出勤記錄集合起來,就是一個「異常報表」的物件了。
,兩個集合物件的單一出勤記錄,怎麼長得不一樣?剛剛不是說明過了嗎?此時物件是沒有長相的概念,重點是該物件應該要具有那些【屬性】,要「拉」那些屬性出來顯示只是視情況而定的,高興的話也可以把它拉成報表。

甚至,為了修改實際上下班時間(由於可能忘記帶卡片了,實際上是有來上班,總該給人家薪水)也可以將單一的出勤記錄「拉」成這樣:

物件的具現化
前面有說過,一筆出勤記錄是一個物件,但是怎麼得到該筆所要的物件呢?接下來會介紹一個在設計模式(Design Pattern)中稱為工廠方法(Factory Mathod)的技巧(目前只是講解概念,詳細說明以及實作會再找另外的時機)。
正常來講,所謂的一筆出勤記錄是代表某一「員工」的某「一天」的出勤記錄,因此先決條件就是要有「員工代號」及「日期」才能查出,因此我們可以設計一個以員工代號及日期為參數,傳回出勤記錄物件的工廠方法。
例:AttendInfomation.GetItem(employeeId,checkDate)
上述的方法,可能是該員工當天的考勤記錄已經計算過了,因為一家公司可能有上佰或上仟的員工,不可能隨時要查一個員工某天的出勤記錄就要隨時計算出來,一般會有一個排程的程式在每天的固定時間將全體員工的前一天的出勤記錄計算出來並存入資料庫,而上述的GetItem方法只是到資料庫撈出資料呈現出來而已。
而排程要用的方法,我們可以另外再設計一個,同樣是一個以員工代號及日期為參數,然後依該參數來找出該員工當天應上下班時間(必須有該員工的正常班表、公司的行事曆、該員工的請假、出差、調班等資訊)再找出該員工的實際上下班時間(必須要有該員工所持卡號),找出後再做成判定並存入資料庫,以備後續查詢。
例:AttendInfomation.Check(employeeId,checkDate)
因為如同前面所示的物件集合,單筆的出勤記錄是一群記錄中的一筆,所以物件集合也是接收某些參數,然後到資料庫中撈出一【組】記錄,因此考勤記錄應該也能接收DataReader當參數,產生一筆物件的工廠方法。
例:AttendInfomation.GetItem(myReader)
方法的再利用
看到這裏,比較沒耐性(或許是習慣舊有方法)的人會認為,怎麼那麼麻煩,又是屬性、又是工廠方法,為什麼要區分的那麼細。寫在一塊也是可以解決問題?!如果我們只是想解決「當前」的問題,這樣講是不錯,但是我們想解決的是「未來」的問題。
前面提過的,有個自動排程的程式,會每天自動計算全公司的考勤記錄,但是在計算之前要先有:該員工的正常班表、公司的行事曆、該員工的請假、出差、調班、該員工所持卡號等資訊才能做出「正確」的判定。如果您的使用者是個盡職的人事,有按時正確地維護這些訊息,那程式可正常的運作。但是如果一個員工的請假(或調班、出差、換卡等)訊息是在自動考勤之後好幾天才維護的呢?
這時只要在該些訊息變動的同時檢查一下,變動所造成的影響是否是已經完成自動考勤之後,如果是只要重新再對該員當日重新考勤一次。
例:
If CheckOk(checkDate)
AttendInfomation.Check(employeeId,checkDate)
End If
加上三行程式碼就解決了,可能不用花到一分鐘,但是該OOXX也是要裝一下啦,怪一下該人事,順便說一下要改這個很難很複雜耶~~~
其它的方法
當然,單筆的出勤記錄應該還要有其它一些方法,比如將修改完後的記錄儲存的方法。修改上下班合理性的檢查方法等。
結論
本篇文章,主要只是想表達一個概念,在程式設計之前最重要的是清楚知道「想做的事情」是什麼,在程式設計前做好事前的規畫可達到事半功倍的效果,而至於如何實作出來只是找適當的程式語言、適當的開發工具,看是要用「拉」的,用程式碼片段來貼、要用程式碼產生器‥‥都是可行的,重點是要清楚知道自己想完成什麼工作,要完成這些工作要有那些程式碼。
或許,有讀者心裏會說,用講的、用掰的誰不會,但是這是一個實際完成的系統,而現在是在寫一篇「文章」不是寫一本「書」,當然不可能把所有實作過程都寫出來。將來如果有機會,阿源哥哥也是希望能從頭講到尾,並付上完整的範例程式。


