表驱动法3
2014-05-25 14:40 ttylinux 阅读(268) 评论(0) 收藏 举报需求:编写一个子程序,打印存储在一份文件中的消息。该文件有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条。
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;
}
}
//------
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的功能。
浙公网安备 33010602011771号