表驱动设计的一点见解
???????昨晚看了CC2的一章,專門講表驅(qū)動設(shè)計的.看了兩三次才看懂了.然后想起了一起自己做過的一個項目的那種劣質(zhì)實現(xiàn)膽戰(zhàn)心驚,真是相逢恨晚呀.
????? 以前做過的一個項目是從一個文本框中輸入一個日期,然后判斷這個日期是否合法,我當(dāng)時的想法是判斷輸入的年份是不是閏年,然后再判斷輸入的月份是不是二月,如果是二月再判斷有沒有超出日期.是不是很暈....如果我們用表驅(qū)動那么我們應(yīng)該得到一下的一個很簡單的實現(xiàn):
?????定義一個二維數(shù)組dayNumber[2][12]其中dayNumber[0]保存一般的非閏年的月份日數(shù),dayNumber[1]保存閏年的月份日數(shù).然后我們只要定義一個函數(shù)int IsLeapYear(int year)是閏年就返回一個1不是返回0,那么對于每一個月份的最大日數(shù)我們都可以這樣子得到了lastDay=dayNumber[isLeapYear(year)][month],沒有長長的If語句.
????? 而在后面CC2上給出了一個更加復(fù)雜的例子.這個例子是這樣子的:
????? 有很多記錄文件,每一個記錄文件記錄著500條數(shù)據(jù),在這些數(shù)據(jù)中共有20中不同的數(shù)據(jù)形式.然后每一條數(shù)據(jù)都由一些field組成,每一種field的計算機表現(xiàn)形式不同.最后,每一種數(shù)據(jù)的數(shù)據(jù)組成方式可能會改變,由客戶決定.現(xiàn)在我們要將數(shù)據(jù)里面的內(nèi)容讀出來顯示在屏幕上.我們會怎么樣做了?
????? 我們?nèi)绻凑彰嫦驅(qū)ο蟮奈覀兙蜁懸粋€抽象的Message來作為每一中數(shù)據(jù)形式的基類,然后再繼承,派生.可是要是用戶再增加類的數(shù)目了?
????? 再CC2里面介紹了用表驅(qū)動法來解決這個問題,我們可以定義一個AbstractField的基類來代表所有的field類型,然后就每一個具體的Field類型寫一個實現(xiàn)類.再定義一個代表各種field類型的枚舉.最后定義一個Message類代表每一個數(shù)據(jù),和定義一個AbstractField類型的數(shù)組,數(shù)組的內(nèi)容有每一種Field類型的實例組成.最后對于每一條數(shù)據(jù)我們都有一下的一種表達方式:
?????? for each field in message
??????????fields[fieldtype].Print(str)
?????? 我們根本上就不用用邏輯判斷去實現(xiàn)這個功能.
下面我給出一個.net的實現(xiàn):
??????????
?
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;
????}
??????? 這是我的實現(xiàn),水平有限,有什么不對的請指正.
???????? 最后謝謝所有上我的blog給我鼓勵和意見的人.謝謝.
轉(zhuǎn)載于:https://www.cnblogs.com/hrmai/archive/2008/08/16/1269318.html
總結(jié)
以上是生活随笔為你收集整理的表驱动设计的一点见解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql 2000 分页
- 下一篇: ubuntu怎么关防火墙