mercredi 10 juillet 2019

Java: Store instance objects in list or use reflection?

how are you? I'm trying to do some dynamic method calls to get sql strings on various objects in Java (Android), but i'm stuck with some questions about performance and stability.

Context Example: Repository class onCreate method get all entity objects (tables) and call a method (getCreateTable for example) to get a sql string to execute.

Sure i can explicit call class by class caling each method, but i have other calls like "dropTables", "truncateTables" and etc, and i do not want to be repeating the same structure all the time.

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());
}

Until now i know i can do that in 3 diferent ways.

1) Using reflection: Basicaly, i store all the objects class in a list, and then use the reflection to call the desired static method.But i know that reflection not always should be the first choice.

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) Storing object instance in list: I can have a list with the objects instanced and then cast then into abstract parent class (or interface) and call the methods to get the sql string. In this case, i don't know if is a good practice to keep an list of instanced objects in memory, maybe this could be worst than use reflection depending on list size.

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) Storing all the strings into JSON object: I don't tested that one yet, but i'm sure with should work. I can call an "init" method to iterate over all objects and create that JSON object/array with all the sql strings (drop, create, truncate and etc).

I really appreciate if you share with me what you think about these approaches (pros and cons) or another better solution.





Aucun commentaire:

Enregistrer un commentaire