需求:编写一个子程序,打印存储在一份文件中的消息。该文件有500条消息,有20种不同类型的消息。
思路:将消息逐条读入,然后,解释该消息,看它是属于哪种类型的,然后,调用针对该类型的打印程序。如此,实现方式,有:1.要写20个if语句,来判断该消息是属于哪种类型;
然后,还需要20个打印子程序。当然,还可以采用继承的方式,写一个抽象类,该抽象类抽象了20种不同类型的消息特征,然后,具体的消息类型是该抽象类的一个子类;但是,
同样要判断该消息类型,同样是要有20个if语句,然后,再实例化相应的子类。
采用表驱动法的思路:一条消息的消息类型,作为Key,在一个消息类型表中找到该消息类型的描述,这是直接查询表,得到该消息的消息类型描述。然后,写一个通用的打印子程序来打印消息。
假如这20种不同类型的消息,它们的特征是这样的:
类型ID;类型描述 |
平均温度;浮点数值 |
温度范围;浮点数值 |
采样点数;整数值 |
测量时间;时间值 |
一条消息,有个头部;然后是每个消息项,一个消息项,由两部分组成,一个是该消息项的名称,一个是该消息项的值类型。
那么,其通用打印子程序就是:
输出一个名称,然后,输出一个数值。
输出名称,这个可以从其对应的消息类型描述中取到;然后根据值类型,调用对应的值类型打印子程序。
如此,某个消息类型改变的时候,假设没有增加新的值类型,那么,也就只需要修改该消息类型的描述,也就是增加一个消息项的名称+消息项的值类型。
即使,增加了一个新的值类型,那么只需要增加一个新的值类型的打印子程序。
整个实现流程:
1.读入一条消息,根据消息的头部类型ID,然后,查表,得到它的类型描述信息。----表驱动法的应用,消除了20个if语句。
2.调用通用打印子程序,一条消息内容3作为输入参数。
通用打印程序:
2.1读出该消息的每个消息项(循环,因为一条消息究竟有多少个消息项是不确定的),然后,读出该消息项的值类型,根据值类型,调用对应的值类型打印子程序。
打印消息项的名称+打印该项的值。
下面为了演示,对内容作了以下限定:
1.消息类型,只有3种。
2.值类型,只有4种。
3.读入的消息条数,只有3条。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 |
import java.util.ArrayList; import java.util.HashMap; import javaProblem.ComplicatedTable.ValueType; public class ComplicatedTable { private
HashMap<MessageType, Object> messageTypeTable = new
HashMap<MessageType, Object>(); public
static enum MessageType { TypeOne, TypeTwo, TypeThree } public
enum ValueType { FloatingPoint, IntegerType, TimeOfDay, StringType } public
static final String IDKey = "IDKey" ; public
static final String ItemsKey = "ItemsKey" ; public
void addNewType(HashMap<String, Object> oneType) { messageTypeTable.put((MessageType) oneType.get(IDKey), oneType); } public
void commonDisplay(HashMap<String, Object> one, TypeUtil util) { @SuppressWarnings ( "unchecked" ) HashMap<String, Object> messageDescrip = (HashMap<String, Object>) messageTypeTable .get(one.get(ComplicatedTable.IDKey)); @SuppressWarnings ( "unchecked" ) ArrayList<String> values = (ArrayList<String>) one .get(ComplicatedTable.ItemsKey); ArrayList<ItemDescrip> itemsDescrip = (ArrayList<ItemDescrip>) messageDescrip .get(ComplicatedTable.ItemsKey); for
( int i = 0 ; i < values.size(); i++) { ItemDescrip oneItem = itemsDescrip.get(i); String value = values.get(i); switch
(oneItem.getValueType()) { case
FloatingPoint: util.displayFLoatPoint(value, oneItem.getLable()); break ; case
IntegerType: util.displayInteger(value, oneItem.getLable()); break ; case
TimeOfDay: util.displayTimeOfDay(value, oneItem.getLable()); break ; case
StringType: util.displayString(value, oneItem.getLable()); break ; } } } public
static void main(String[] args) { TypeUtil util = new
TypeUtil(); ComplicatedTable oneTable = new
ComplicatedTable(); oneTable.addNewType(util.initalTypeOne()); oneTable.addNewType(util.initalTypeTwo()); oneTable.addNewType(util.initalTypeThree()); ArrayList<HashMap<String, Object>> messages = new
ArrayList<HashMap<String, Object>>(); // 模拟从文件中读出的数据 HashMap<String, Object> oneMessage = new
HashMap<String, Object>(); ArrayList<String> itemsOne = new
ArrayList<String>(); itemsOne.add( "43.3" ); itemsOne.add( "高温" ); oneMessage.put(ItemsKey, itemsOne); oneMessage.put(IDKey, MessageType.TypeOne); messages.add(oneMessage); HashMap<String, Object> twoMessage = new
HashMap<String, Object>(); ArrayList<String> itemsTwo = new
ArrayList<String>(); itemsTwo.add( "中国" ); itemsTwo.add( "13" ); twoMessage.put(ItemsKey, itemsTwo); twoMessage.put(IDKey, MessageType.TypeTwo); messages.add(twoMessage); HashMap<String, Object> threeMessage = new
HashMap<String, Object>(); ArrayList<String> itemsThree = new
ArrayList<String>(); itemsThree.add( "2012-04-30" ); itemsThree.add( "13" ); threeMessage.put(ItemsKey, itemsThree); threeMessage.put(IDKey, MessageType.TypeThree); messages.add(threeMessage); // 读入消息,然后打印消息;通过采用表驱动法,消除了if判断 for
( int i = 0 ; i < messages.size(); i++) { oneTable.commonDisplay(messages.get(i), util); } } } class
ItemDescrip { private
String Label; private
ValueType valueType; public
void setDescrip(String label, ValueType valueType) { this .Label = label; this .valueType = valueType; } public
String getLable() { return
Label; } public
ValueType getValueType() { return
valueType; } } |
//------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 |
import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import javaProblem.ItemDescrip; import javaProblem.ComplicatedTable.MessageType; import javaProblem.ComplicatedTable.ValueType; public class TypeUtil { public
HashMap<String, Object> initalTypeOne() { HashMap<String, Object> typeOne = new
HashMap<String, Object>(); typeOne.put(ComplicatedTable.IDKey, MessageType.TypeOne); ArrayList<ItemDescrip> items = new
ArrayList<ItemDescrip>(); ItemDescrip one = new
ItemDescrip(); one.setDescrip( "Average_temperature" , ValueType.FloatingPoint); items.add(one); ItemDescrip two = new
ItemDescrip(); two.setDescrip( "Temperature_alias" , ValueType.StringType); items.add(two); typeOne.put(ComplicatedTable.ItemsKey, items); return
typeOne; } public
HashMap<String, Object> initalTypeTwo() { HashMap<String, Object> typeTwo = new
HashMap<String, Object>(); ArrayList<ItemDescrip> items = new
ArrayList<ItemDescrip>(); typeTwo.put(ComplicatedTable.IDKey, MessageType.TypeTwo); ItemDescrip one = new
ItemDescrip(); one.setDescrip( "Location" , ValueType.StringType); items.add(one); ItemDescrip two = new
ItemDescrip(); two.setDescrip( "Amount" , ValueType.IntegerType); items.add(two); typeTwo.put(ComplicatedTable.ItemsKey, items); return
typeTwo; } public
HashMap<String, Object> initalTypeThree() { HashMap<String, Object> typeThree = new
HashMap<String, Object>(); typeThree.put(ComplicatedTable.IDKey, MessageType.TypeThree); ArrayList<ItemDescrip> items = new
ArrayList<ItemDescrip>(); ItemDescrip one = new
ItemDescrip(); one.setDescrip( "Day" , ValueType.TimeOfDay); items.add(one); ItemDescrip two = new
ItemDescrip(); two.setDescrip( "Amount" , ValueType.IntegerType); items.add(two); typeThree.put(ComplicatedTable.ItemsKey, items); return
typeThree; } public
void displayFLoatPoint(String value, String label) { // 对应的其它格式化措施 System.out.println(label + "; value:"
+ value); } public
void displayInteger(String value, String label) { // 其它格式化措施 System.out.println(label + "; value:"
+ value); } public
void displayString(String value, String label) { // 对应的其它格式化措施 System.out.println(label + "; value:"
+ value); } public
void displayTimeOfDay(String value, String label) { // 对应的其它格式化措施 System.out.println(label + "; value:"
+ value); } } |
运行的输出结果:
Average_temperature; value:43.3
Temperature_alias;
value:高温
Location; value:中国
Amount; value:13
Day;
value:2012-04-30
Amount; value:13
如此,在有新的消息类型的时候,只要往TypeUtil中添加新的消息类型描述便可;如果有新的值类型,同样只要往TypeUtil中添加新的打印子程序便可。
当然,还可以再继续优化。优化到,对外提供一个添加消息类型的接口,然后,用户只要添加新的消息类型;然后,自己也可以实现自己要打印的消息子程序。
--------总之,本文,再次展示,采用表驱动法来消除if的功能。
原文:http://www.cnblogs.com/ttylinux/p/3751181.html