Разбор / Загрузка объектов с диска - PullRequest
0 голосов
/ 24 октября 2018

Я разрабатываю программу, которая читает разные данные в разных форматах из файлов.Чтобы объяснить мои потребности и для ясности, вот пример (действительно минимальный / простой пример, форматы данных довольно сложны в реальности)

public class Person{
    private final String name;

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

    public String getName(){return name;}
}

Затем мне нужно создать экземпляр Person класс, использующий файл, который имеет следующий формат:

name = Bob

(Примечание: в этом примере я использую формат свойств java, но на самом деле формат отличается, и существует огромное количество данных. Например,один из классов, который я хочу загрузить, имеет более 50 полей (включая double / String / arrays). Он загружается из файлов ~ 30M и формат фиксирован)

Для загрузки этих файлов я подумал о 3 способах:

Первый: Предоставить статический метод фабрики:

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

Но класс person должен быть просто классом «данных», и с этим подходом мне приходится иметь делос IOException в классе «данных», который кажется странным.Более того, загрузка экземпляра моих объектов (на самом деле) может быть довольно сложной и подразумевает множество методов / утилит для работы с файлами регулярных выражений / java, которые не относятся к классу Person.

Секунда: Укажитеслужебный класс:

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 голосов
/ 24 октября 2018

Я думаю, что вы можете иметь универсальный загрузчик (вы также можете сделать его синглтоном)

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 для создания экземпляров объектов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...