zoukankan      html  css  js  c++  java
  • 表驱动法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条。

    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的功能。

    版权声明:
    作者:ttylinux
             
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    strcpy
    Apple Swift中英文开发资源集锦[apple swift resources]
    c/c++指针总结[pointer summary]
    TestPointer
    66. 有序数组构造二叉搜索树[array to binary search tree]
    HDU 2112 HDU Today
    HDU 3790 最短路径问题
    HDU 2544 最短路
    模拟赛 Problem 3 经营与开发(exploit.cpp/c/pas)
    模拟赛 Problem 2 不等数列(num.cpp/c/pas)
  • 原文地址:https://www.cnblogs.com/ttylinux/p/3751181.html
Copyright © 2011-2022 走看看