首页 > 代码库 > 表驱动法3
表驱动法3
需求:编写一个子程序,打印存储在一份文件中的消息。该文件有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 = http://www.mamicode.com/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的功能。