SS-Lab3 读取不同对象类型的统一实现

一、参考情景

  • 接收客户端输入的不同的对象(一个或多个)信息
  • 不同对象的属性可能不同
  • 将对象(一个或多个)插入到对应的集合中

共性

  • 接收信息
  • 根据信息创建对象
  • 将对象插入集合

不同

  • 接收到的对象的个数
  • 对象的属性

功能分析

  • readObjectAttributes() : 读取用户输入的对象属性
  • buildObjectFromAttributes() : 根据对象属性生成对象实例
  • insertObjectIntoSet() : 将对象插入集合中

二、实现方案

方案一

  • 每次读取一条信息,生成一个实例,插入一个元素,与用户输入同步,类似于
for(;;) {
    
    
	readObjectAttributes();
	buildObjectFromAttributes();
	insertObjectIntoSet();
}
方案评估
- 模块之间数据交换频繁
- 不便于测试
- 出错难以定位

方案二

  • 一次性读取所有输入,生成所有实例,插入所有元素,在用户输入结束后实现,类似于
for(;;) {
    
    
	readObjectAttributes();
}
buildObjectFromAttributes();
insertObjectIntoSet();

三、实现思路

readObjectAttributes

  • Object可能有intdoubleString等不同类型的属性
  • readObject() : 我只负责读数据,所有数据类型在我这都是String,转换我不负责!
  • buildObjectFromAttributes() : 好好好,数据转换是我的事,可你总要保证给我的数据是能转换的吧!intValueOf("3.14")这责任可不在我啊
  • readObjectAttributes : 放心,正则兄弟会替我解决的

buildObjectFromAttributes

  • 由于不同的对象具有不同的属性,因此需要对readObjectAttributes传来的数据进行适配
  • 每一个对象类型需要实现自己的适配器
  • 适配完以后就可以依次new出各个对象实例了

insertObjectIntoSet

  • 有了对象实例,插入就很简单了

四、ObjectUpdater适配器接口

功能

  • AttributeString转换为对应的Attribute数据
  • 根据转换后的Attribute生成Object
  • 因为适配完后均须插入到集合中,因此将插入作为接口的默认方法
  • 可变参数参考
public interface ObjectUpdater<L> {
    
    

	public default void insertObjects(Set<L> objectSet, L ... objects) {
    
    
		for(L object: objects) {
    
    
			if(!objectSet.contains(object)) {
    
    
				objectSet.add(object);
			}
		}
	}
	
	/**
	 * @method buildObjects
	 * @param attributes that the object have
	 * 			attributes[0] contains the first attribute of all the objects and so on
	 * @return an array of objects with the given attributes
	 * */
	public L[] buildObjects(String[] ... attributes);
}

五、具体实现

readObjectAttributes

public String[] readAtrributeArray(String name, String attr, int objectCount) {
    
    
	String[] attributes = new String[objectCount];
	for(int i = 0; i < objectCount; i++) {
    
    
		attributes[i] = readString(attr, name + " " + (i + 1));
	}
	return attributes;
}

public String[][] readObjectAttributes(String objectClass, String[] attrs, int objectCount) {
    
    
	String[][] attributes = new String[attrs.length][];
	for(int i = 0; i < attrs.length; i++) {
    
    
		attributes[i] = readAtrributeArray(objectClass, attrs[i], objectCount);
	}
	return attributes;
}

buildObjectFromAttributes

  • 直接通过适配器实现
L objects = objectlUpdater.buildObjects(attributes);

insertObjectIntoSet

  • 通过适配器默认方法实现
objectlUpdater.insertObjects(objectSet, objects);

一步实现对象的构建和插入

public void addGroupOfObjects(String[] ... attributes) {
    
    
	objectlUpdater.insertObjects(objectSet, 
				objectlUpdater.buildObjects(attributes));
}

六、客户端调用

实现针对某一对象的适配器

  • Course
public class Course {
    
    
	private int id;
	private String name;
	private String teacher;
	private String classroom;
	private int hoursOfWeek;
}
  • CourseUpdater
public class CourseUpdater implements ObjectUpdater<Course> {
    
    

	@Override
	public Course[] buildObjects(String[]... attributes) {
    
    
		Course[] courses = new Course[attributes[0].length]; // the number of attributes
		for(int i = 0; i < attributes[0].length; i++) {
    
    
			courses[i] = new Course(Integer.valueOf(attributes[0][i]), attributes[1][i], 
					attributes[2][i], attributes[3][i], Integer.valueOf(attributes[4][i]));
		}
		return courses;
	}
}

接收用户输入

  • 针对属性的读取,即连续输入多个对象的同一属性,依次输入所有属性(本例使用,直接调用readObjectAttributes即可)
  • 针对对象的读取,每次输入一个对象的所有属性

实现对象插入

  • 直接调用addGroupOfObjects即可

完整代码

private static final String MEM_CLASS = "Course";
private static final String[] CLASS_ATTR = new String[] {
    
    
		"id", "name", "teacher", "classroom", "hoursOfWeek"
};
private static void addGroupOfCourses() {
    
    
	int coursesCount = myReader.readInt(false, 0, 0, "number of new courses");
	String[][] attributes = myReader.readObjectAttributes(MEM_CLASS, CLASS_ATTR, courseCount);
	courseIntervalSet.addGroupOfCourses(attributes);
}

猜你喜欢

转载自blog.csdn.net/weixin_39578432/article/details/118602100
今日推荐