OOP h18
构造一个「类厂」:MyClassFactory
该类能够用一个 .ini 文件初始化,.ini 文件的格式参考 my_config.ini,测试的时候这个文件名字可能改变,文件中包括中文,且文件一定为 UTF-8 编码
.ini 文件中描述了这个类厂能够动态创建的类和类的初始属性
动态构造各种类,并且用.ini中的属性初始化,测试的时候 类名可能变化,例如  Orange.class ….
测试的时候,可能给其他对象,测试时候给的对象一定满足如下条件:
- 有空的构造函数
- 其中只包括了 Integer,String 两种属性,并且有 setXxx getXxx 方法
将要动态创建的“类”抽象成 Param 类。
0x00 Param
该类应该具有成员变量,存储“类”和属性的对应关系(Map),而属性和属性值也具有对应关系(Map)。
Param 包含成员变量 allParamsMap,类型为 Map<String, Map<String, Object>>。
构造方法可以直接调用 readLines 读取文件转换格式。
新建 getParamMap 方法,返回对应“类”名的属性映射 Map<String, Object>。
完整代码:
| 12
 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
 
 | package com.huawei.classroom.student.h18;
 import java.io.*;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 
 
 
 
 public class Param {
 
 
 
 private final Map<String, Map<String, Object>> allParamsMap = new HashMap<>();
 
 public Param(String filename) throws IOException {
 readLines(filename);
 }
 
 public Map<String, Object> getParamMap(String className) {
 return allParamsMap.get(className);
 }
 
 private void readLines(String filename) throws IOException {
 InputStream in = new FileInputStream(filename);
 InputStreamReader inReader = new InputStreamReader(in, StandardCharsets.UTF_8);
 LineNumberReader lineReader = new LineNumberReader(inReader);
 String line = lineReader.readLine();
 
 while (line != null) {
 if (line.startsWith("#") || line.trim().length() == 0) {
 
 } else {
 
 String[] strs = line.split("=");
 String left = strs[0];
 String right = strs[1];
 
 int dotPos = left.lastIndexOf(".");
 String className = left.substring(0, dotPos);
 String paramName = left.substring(dotPos + 1);
 
 Map<String, Object> paramMap = null;
 if (allParamsMap.containsKey(className)) {
 paramMap = allParamsMap.get(className);
 } else {
 paramMap = new HashMap<>();
 }
 
 if (right.startsWith("\"")) {
 paramMap.put(paramName, right.substring(1, right.length() - 1));
 } else {
 paramMap.put(paramName, Integer.parseInt(right));
 }
 allParamsMap.put(className, paramMap);
 }
 line = lineReader.readLine();
 }
 }
 }
 
 | 
0x01 MyClassFactory
动态调用赋值,需要给“类”新建 setter 方法(getter 是 Test 用的)。
完整代码:
| 12
 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
 
 | package com.huawei.classroom.student.h18;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
 
 
 
 
 public class MyClassFactory {
 private final Param params;
 
 public MyClassFactory(String filename) throws IOException {
 params = new Param(filename);
 }
 
 
 
 
 
 
 
 
 public <T> T createInstance(Class<T> clazz)
 throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
 String className = clazz.getName();
 T t = clazz.newInstance();
 Map<String, Object> paramMap = params.getParamMap(className);
 for (String param : paramMap.keySet()) {
 Object value = paramMap.get(param);
 String methodName = "set" + param.substring(0, 1).toUpperCase() + param.substring(1);
 dynamicInvokeMethod(t, methodName, value);
 }
 return t;
 }
 
 
 
 
 public void dynamicInvokeMethod(Object obj, String methodName, Object... values)
 throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
 int i;
 Class<?>[] classes = new Class[values.length];
 for (i = 0; i < values.length; i++) {
 classes[i] = values[i].getClass();
 }
 Method method = obj.getClass().getMethod(methodName, classes);
 method.invoke(obj, values);
 }
 }
 
 |