Java: использовать отражение или хранить объекты экземпляра в списке? - PullRequest
0 голосов
/ 10 июля 2019

как дела?Я пытаюсь выполнить некоторые динамические вызовы методов, чтобы получить строки sql для различных объектов в Java (Android), но я застрял с некоторыми вопросами о производительности и стабильности.

Пример контекста: Метод репозитория onCreate получает все объекты сущностей (таблицы) и вызывает метод (например, getCreateTable), чтобы получить строку sql для выполнения.

Конечно, я могу явно вызывать класс по классу, вызывающему каждый метод, но у меня естьдругие вызовы, такие как «dropTables», «truncateTables» и т. д., и я не хочу постоянно повторять одну и ту же структуру.

public void CreateTables() {
    execute(Entity1.getCreateTable());
    execute(Entity2.getCreateTable());
    execute(Entity3.getCreateTable());
    [..]
    execute(Entity50.getCreateTable());
}

public void DropTables() {
    execute(Entity1.getDropTable());
    execute(Entity2.getDropTable());
    execute(Entity3.getDropTable());
    [..]
    execute(Entity50.getDropTable());
}

До сих пор я знаю, что могу сделать это тремя разными способами.

1) Использование отражения (используется в настоящее время): По сути, я сохраняю все классы объектов в списке, а затем использую отражение для вызова нужного статического метода. Но я знаю, чтоотражение не всегда должно быть первым выбором.

private final List<Class> entityList = new ArrayList<Class>() {
    {
        add(Entity1.class);
        add(Entity2.class);
        add(Entity3.class);
    }
};

public void createTables() {
    /* get all query strings */
    List<String> queryList = getQueryList("createTable");

    try {
        for (String query : queryList) {
            execute(query);
        }
    } catch (SQLException e) {
        [...]
    }
}

private List<String> getQueryList(String methodName) {
    List<String> queryList = new ArrayList<>();

    for (Class<?> objectClass : entityList) {
        try {
            Method[] ms = objectClass.getMethods();
            for (Method me : ms) {
                if (me.getName().equals(methodName)) {
                    String query = (String) me.invoke(null);

                    if (query != null && query.length() > 0) {
                        queryList.add((String) me.invoke(null));
                    }

                    break;
                }
            }
        } catch (Exception e) {
            [...]
        }
    }

    return queryList;
}

2) Сохранение экземпляра объекта в списке: Я могу получить список с экземплярами объектов и затем привести then в абстрактный родительский класс (или интерфейс) и вызов метода для получения строки sql.В этом случае я не знаю, является ли хорошей практикой хранение списка экземпляров объектов в памяти, возможно, это может быть хуже, чем использование отражения в зависимости от размера списка.

private final List<BaseEntity> entityList = new ArrayList<BaseEntity>() {
    {
        add(new Entity1(context));
        add(new Entity2(context));
        add(new Entity3(context));
    }
};

public void createTables() {
    for (BaseEntity entity : entityList) {
        try {
            execute(entity.getCreateTable());
        } catch (Exception e) {
            [...]
        }
    }
}

3) Сохранение всех строк в объекте JSON: Я еще не тестировал эту строку, но уверен, что она должна работать.Я могу вызвать метод "init", чтобы перебрать все объекты и создать этот объект / массив JSON со всеми строками sql (drop, create, truncate и т. Д.).

Я очень признателен, если вы поделитесь со мной тем, чтоВы думаете об этих подходах (за и против) или другом лучшем решении.

1 Ответ

0 голосов
/ 16 июля 2019

Как отмечено в комментариях, это был явно плохой дизайн (это старый проект, который я рефакторинг). Поэтому я решил отвлечься от размышлений и потратить некоторое время на переработку самого кода.

Я создал базовый суперкласс для обработки всех похожих методов и позволил сущностям / моделям реализовывать только необходимые индивидуальные правила, поэтому доступ к БД хранится только в одном классе как Singleton. Гораздо лучше использовать полиморфизм интерфейса.

Таким образом, класс db обрабатывает динамическое генерирование SQL, чтобы избежать повторения одного и того же кода везде и повторно использовать / перерабатывать список экземпляров для повышения производительности.

набл. 1: Отражение снижает производительность и, как правило, затрудняет отладку. Конечно, это может сэкономить некоторое время, поскольку это быстро реализуется, но отключит большинство функций IDE, что в большинстве случаев делает его бесполезным.

набл. 2: Никогда не следует поддерживать активный список экземпляров БД. Никогда не рекомендуется иметь доступ к базе данных одновременно для нескольких экземпляров, это может привести к блокировке БД и воспроизведению непредвиденных проблем.

набл. 3: Эта штука JSON ... забудь об этом. Прошу прощения за то, что предложил что-то такое уродливое.

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