表驱动设计的一点见解
???????昨晚看了CC2的一章,專門講表驅動設計的.看了兩三次才看懂了.然后想起了一起自己做過的一個項目的那種劣質實現膽戰心驚,真是相逢恨晚呀.
????? 以前做過的一個項目是從一個文本框中輸入一個日期,然后判斷這個日期是否合法,我當時的想法是判斷輸入的年份是不是閏年,然后再判斷輸入的月份是不是二月,如果是二月再判斷有沒有超出日期.是不是很暈....如果我們用表驅動那么我們應該得到一下的一個很簡單的實現:
?????定義一個二維數組dayNumber[2][12]其中dayNumber[0]保存一般的非閏年的月份日數,dayNumber[1]保存閏年的月份日數.然后我們只要定義一個函數int IsLeapYear(int year)是閏年就返回一個1不是返回0,那么對于每一個月份的最大日數我們都可以這樣子得到了lastDay=dayNumber[isLeapYear(year)][month],沒有長長的If語句.
????? 而在后面CC2上給出了一個更加復雜的例子.這個例子是這樣子的:
????? 有很多記錄文件,每一個記錄文件記錄著500條數據,在這些數據中共有20中不同的數據形式.然后每一條數據都由一些field組成,每一種field的計算機表現形式不同.最后,每一種數據的數據組成方式可能會改變,由客戶決定.現在我們要將數據里面的內容讀出來顯示在屏幕上.我們會怎么樣做了?
????? 我們如果按照面向對象的我們就會寫一個抽象的Message來作為每一中數據形式的基類,然后再繼承,派生.可是要是用戶再增加類的數目了?
????? 再CC2里面介紹了用表驅動法來解決這個問題,我們可以定義一個AbstractField的基類來代表所有的field類型,然后就每一個具體的Field類型寫一個實現類.再定義一個代表各種field類型的枚舉.最后定義一個Message類代表每一個數據,和定義一個AbstractField類型的數組,數組的內容有每一種Field類型的實例組成.最后對于每一條數據我們都有一下的一種表達方式:
?????? for each field in message
??????????fields[fieldtype].Print(str)
?????? 我們根本上就不用用邏輯判斷去實現這個功能.
下面我給出一個.net的實現:
??????????
?
Codeclass?Program
????{
????????private?static?AbstractField[]?array?=?new?AbstractField[]?{?new?IntField(),?new?ObjField(),?new?StrField()?};
????????static?void?Main(string[]?args)
????????{
????????????Message?m?=?new?Message();
????????????m.AddFieldToMessage(FieldType.IntegerField,?"10000");
????????????m.AddFieldToMessage(FieldType.ObjectField,?"object");
????????????m.AddFieldToMessage(FieldType.StringField,?"string");
????????????List<field>?fields?=?m.GetFields();
????????????int?count?=?fields.Count;
????????????int?index?=?0;
????????????while?(index?<?count)
????????????{
????????????????array[(int)fields[index].type].PrintMessageField(fields[index].body);
????????????????index++;
????????????}
????????????Console.Read();
????????}
????}
????class?Message
????{
????????
????????private?List<field>?fields;
????????public?void?AddFieldToMessage(FieldType?type,?string?body)
????????{
????????????field?addField?=?new?field();
????????????addField.body?=?body;
????????????addField.type?=?type;
????????????fields.Add(addField);
????????}
????????public?List<field>?GetFields()
????????{
????????????return?fields;
????????}
????????public?Message()
????????{
????????????fields?=?new?List<field>();
????????}
????}
????abstract?class?AbstractField
????{
????????public?virtual?void?PrintMessageField(string?body)
????????{
????????????throw?new?Exception("this?method?must?be?implement");
????????}
????}
????class?IntField?:?AbstractField
????{
????????public?override?void?PrintMessageField(string?body)
????????{
????????????Console.WriteLine("print?from?IntField:{0}",?body);
????????????//base.PrintMessageField(body);
????????}
????}
????class?StrField?:?AbstractField
????{
????????public?override?void?PrintMessageField(string?body)
????????{
????????????Console.WriteLine("Print?from?strField:{0}",?body);
????????????//base.PrintMessageField(body);
????????}?
????}
????class?ObjField?:?AbstractField
????{
????????public?override?void?PrintMessageField(string?body)
????????{
????????????Console.WriteLine("Print?from?objField:{0}",?body);
????????????//base.PrintMessageField(body);
????????}
????}
????enum?FieldType?:?int
????{
????????IntegerField?=?0,
????????StringField,
????????ObjectField
????}
??struct?field
????{
????????public?FieldType?type;
????????public?string?body;
????}
??????? 這是我的實現,水平有限,有什么不對的請指正.
???????? 最后謝謝所有上我的blog給我鼓勵和意見的人.謝謝.
轉載于:https://www.cnblogs.com/hrmai/archive/2008/08/16/1269318.html
總結
以上是生活随笔為你收集整理的表驱动设计的一点见解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql 2000 分页
- 下一篇: 优化网站性能 提高网站速度访问速度的14