Использование Reflection для создания текстового меню - PullRequest
0 голосов
/ 03 декабря 2011

Я использую модифицированную версию системы текстового меню JosAH и пытаюсь выяснить, как использовать отражение для создания списка элементов из объявленных подклассами класса. Поскольку разные элементы меню используют разные параметры для манипулирования базовыми данными, у меня возникла проблема с обобщением их реализации.

Например, задание состояло в том, чтобы создать пользовательский связанный список, поэтому пункты меню будут состоять из Print, Insert, Save, Quit и т. Д. Для печати и вставки просто необходима ссылка на связанный список, чтобы проанализировать ввод и вызвать соответствующие функции в связанном списке. Save дополнительно требует сохранения файла в то время, как Quit не требует никаких дополнительных аргументов.

public class MenuList extends TextMenu { //TextMenu extends MenuItem
    List<MenuItem> items;

    public MenuList (Object data, File file) {} //calls fillList

    //calls createList which fills a List<MenuItem> and copies it to this.items
    protected void fillList(Object data, File file) {
        this.items.addAll( createList(this.getClass(), ... args?) );
    }

    private static class MenuQuit extends MenuItem {
        public MenuQuit() {} //does not need data
    }

    private static class MenuOne extends MenuItem {
        public MenuOne(Object data) {} //manipulates data
    }

    private static class MenuTwo extends MenuItem {
        public MenuOne(Object data) {} //also manipulates data
    }

    private static class MenuThree extends MenuItem {
        //manipulates data and saves to file
        public MenuThree(Object data, File file) {} 
    }

    private static class NestedMenu extends MenuList {
        //needs parameters to pass to it's own menuItems
        public NestedMenu(Object data, File file) {}    
    }
}

public static List<MenuItem> createList(Class cls, ...args? ) {
    List<MenuItem> items = new ArrayList<MenuItem>();
    try {
        Classes<?>[] param = { parse(args)? };
        Class<?>[] menuList = cls.getDeclaredClasses();

        for(Class<?> c : menuList) {
            if(MenuItem.class.isAssignableFrom(c)) {//only adding the MenuItems
                Constructor<?> ct = c.getConstructor(param);
                Object menuItem = ct.newInstance( ...args? );
                items.add( (MenuItem) menuItem );
            }
        }
    } catch (Exception e) { }
}

Есть ли способ обобщить createList, чтобы пункты меню создавались с необходимыми параметрами?

Кроме того, из-за того, как долго я работаю над этим, я полностью открыт для возможности того, что это полностью переосмысленное решение, и что я должен отказаться от больших частей или, возможно, от всей этой идеи.

Редактировать: Я не знаю, является ли это лучшим местом для добавления этой информации Это было решение, о котором я думал, и после прочтения некоторых ответов и комментариев оно могло бы быть правильным. Если MenuItem всегда принимает один объект в качестве параметра, я могу сделать это предположение при вызове getConstructor и newInstance. После этого я просто оставлю это конкретному классу, чтобы преобразовать Object во что-то полезное, из чего они могут получить данные.

public class MenuItem {
    Object data;
    public MenuItem(Object data) {
        this.data = data;
        parseData();
    }
    protected abstract void parseData();
}

private static class MenuQuit extends MenuItem {
    public MenuQuit(Object data) { super(data) } //nothing additional needed
    protected void parseData() {} //does nothing
}

private static class MenuSave extends MenuItem { //as outlined above
    private CustomLinkedList list;
    private File saveFile;
    public MenuSave(Object data) {
        super(data);
    }

    //may be able to use reflection to generalize this
    protected void parseData() { 
        this.list = ((MyCustomData) data).list;
        this.saveFile = ((MyCustomData) data).saveFile;
    }
}

public class MyCustomData {
    public CustomLinkedList list;
    public File saveFile;
    public int otherData;
    public MyCustomData(CustomLinkedList a, File b, int c) {} //assignment
}

Я пытался избежать этого метода, потому что он начинает добавлять сложность к подклассу MenuItems, который я надеялся сделать как можно более простым. Есть ли способ улучшить это решение?

Ответы [ 2 ]

0 голосов
/ 03 декабря 2011

Хммм.Что бы произошло, если бы у вас были аргументы в случаях, когда данные не нужны, и просто игнорировали их?

0 голосов
/ 03 декабря 2011

Не совсем ответ,
но поскольку я, как правило, не большой поклонник размышлений, вот еще одна идея:

Вы можете добавить data и file к базовому классу MenuItem и оставить их null там, где они неприменимы.

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