从磁盘解析/加载对象

时间:2018-10-24 09:07:48

标签: java oop parsing loading

我正在开发一个程序,该程序可以从文件中读取具有不同格式的不同数据。为了说明我的需求并为清楚起见,这里有一个示例(实际上是最小/简单示例,实际上数据格式非常复杂)

public class Person{
    private final String name;

    public Person(String name){
        this.name = Objects.requireNonNull(name);
    }

    public String getName(){return name;}
}

然后,我需要使用以下格式的文件创建Person类的实例:

name = Bob

(NB:在此示例中,我使用Java属性格式,但实际上,格式不同,并且有大量数据。例如,我要加载的类之一具有50多个字段(包括double /字符串/数组)。它是从〜30M文件加载的,并且格式是固定的)

要加载这些文件,我考虑了3种方法:

首先::提供静态工厂方法:

public class Person{
    /*Fields, Constructors, Getters, ... */
    //...
    public static Person fromFile(Path path){/*implementation*/}
}

但是person类应该只是一个“数据”类,通过这种方法,我不得不在“数据”类中处理IOException,这似乎很奇怪。 而且,加载我的对象的实例(实际上)可能非常复杂,并且包含许多与Person类无关的方法/ regex / java文件实用程序。

第二个:提供实用程序类:

public final class PersonLoader{
    /**Prevents instantiation*/
    private PersonLoader(){}

    public static Person load(Path path){/*implementation*/}
}

这种方法的主要问题是,一旦发布它们,我应该维护这两个类。我发现没有办法强制(使用编译器)拥有专用的实用程序类。如果在2个月内添加其他格式,我会考虑添加实用程序类吗? (我的猜测:不)

第三::使用加载程序实例加载我的Person

这可能是这样的外部或内部类(也可以是单例):

 public (static) class PersonLoader{
     public PersonLoader(){}

     public Person load(){/*implementation*/}
 }

如果我将其用作内部类(静态版本),则此方法似乎结合了先前方法的两个缺点。 如果我将其用作顶级类,则维护问题仍然存在,并且每次需要加载数据时都需要创建另一个对象实例。 即使我使用单例模式,让20个单例(对于我使用的每种格式)似乎也不是一个好主意。

还有另一种方法吗?还是应该重构其中一种方法以满足自己的需求?

1 个答案:

答案 0 :(得分:0)

我认为您可以拥有一个通用的加载程序(也可以使其成为单例)

public class ObjectLoader<OBJECT_TYPE> {

    public  OBJECT_TYPE create(Class<OBJECT_TYPE> type, String path){
        OBJECT_TYPE newObj = null;
        try{
            newObj = type.newInstance();
            Field[] declaredFields = type.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                declaredField.set(newObj, "PUT HERE NECESSARY VALUE ");

        }
        }catch (InstantiationException e) {
            //TODO: Handle error
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            //TODO: Handle error
            e.printStackTrace();
        }
        return newObj;
    }
}

并使用Java反射实例化对象