Java "instanceof" to add multiple lists

I'm currently trying to reorganize my code after reading that implementation is preferable to extensions. I'm currently trying to create a function that adds an object to the scene. To better define what each object is, there are several lists, such as a list for updating, rendering, etc.

private List<Updatable> updatables;
private List<Removable> removables;
private List<Renderable> renderables;
private List<Collidable> collidables;

I want to make a function in my Scene class as follows:

public void add(Object o) {
    if(o instanceof Updatable)
        updatables.add((Updatable) o);
    if(o instanceof Removable)
        removables.add((Removable) o);
    if(o instanceof Renderable)
        renderables.add((Renderable) o);
    if(o instanceof Collidable)
        collidables.add((Collidable) o);
}

, . , , instanceof, -, , / , ? , .

+4
5

Factory, Map

static Map<String, List> maps = new HashMap<>();
static {
    maps.put(Updatable.class.getName(), new ArrayList<Updatable>());
    maps.put(Removable.class.getName(), new ArrayList<Removable>());
    maps.put(Renderable.class.getName(), new ArrayList<Renderable>());
    maps.put(Collidable.class.getName(), new ArrayList<Collidable>());
}
public static void add(Object obj){
    maps.get(obj.getClass().getName()).add(obj);
}
+1

: add(Updateable u), add(Removable r), ..

+2

, . Updatable, Removable, Renderable Collidable - . , . , add , . ( , .)

, , :

private List<Updatable> updatables;
private List<Removable> removables;
private List<Renderable> renderables;
private List<Collidable> collidables;

@SuppressWarnings("unchecked")
public void add(Object o) {
    try {
        for (Class c : o.getClass().getInterfaces()) {
            // Changes "Updatable" to "updatables", "Removable" to "removables", etc.
            String listName = c.getSimpleName().toLowerCase() + "s";

            // Adds o to the list named by listName.
            ((List) getClass().getDeclaredField(listName).get(this)).add(o);
        }
    } catch (IllegalAccessException e) {
        // TODO Handle it
    } catch (NoSuchFieldException e) {
        // TODO Handle it
    }
}

, :

  • , , .
  • , . , Foo implements Updatable, Removable, Bar extends Foo, getClass().getInterfaces() Bar . , ClassUtils.getAllInterfaces Apache Commons Lang.
+1

, add , :

public void addUpdatable(Updatable updatable) {
    updatables.add(updatable);
}

public void addRemovable(Removable removable) {
    removables.add(removable);
}

// and so on

, , , API , .

, ( EJP) , , Updatable, Removable, . , , , , ( ) .

, , . , .

0

@Jerry06, - getter.

private Map<Class, List> maps = new HashMap<>();

'maps' , .

private <T> List<T> get(Class<T> c) {
    return maps.get(c);
}

instead of using maps.get, I just use get (SomeClass.class). The function above will automatically convert it to a list with the correct item type. Then I could:

    get(Updatable.class).stream().filter(Updatable::isAwake).forEach(Updatable::update);

instead:

    updatables.stream().filter(Updatable::isAwake).forEach(Updatable::update);

I basically need a structure so that all lists can be well wrapped, and secondly, I could just say maps.add (SomeNewClass.class, new ArrayList ()), and then call it whenever I want.

0
source

Source: https://habr.com/ru/post/1665059/


All Articles