Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Требуется помощь в преобразовании извращений, Рефакторинг кода 
:(
    Опции темы
Kizja
Дата 7.2.2010, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 15.7.2007

Репутация: нет
Всего: нет



Есть консольная программа, которая должна обрабатывать определённые входные данные и потом производить некие манипуляции и выводить результат. Данные могут быть введены как через консоль, считаны из файла (возможны разные типы и соответственно структура данных — не только скажем в xml формате),  взяты из базы итд. Так же и с выводом  обработанных введённых данных. То, какой тип использовать задаётся через консоль, т.е. возможны варианты:

-xml input.xml -xml output.xml
-console -xml output.xml
-xml input.xml -console
-console -console

( вместо -xml возможны ещё другие типа -txt, -csv итд )

Решил для каждого варианта входных и выходных типов сделать свой класс, который будет заниматься преобразованием в однородный тип данных перед обработкой информации.

В результате получилось примерно следующий не очень приятный код (очень смущает куча if-условий):

Код

    private static final String CONSOLE_HANDLER = "-console";
    private static final String CSV_HANDLER = "-csv";
    private static final String DATABASE_HANDLER = "-db";
    private static final String XML_HANDLER = "-xml";
    private static final String HTML_HANDLER = "-html";
    
    private InputHandler inputHandler;
    private OutputHandler outputHandler;
    
    private void initHandlers(String[] args) throws ActionNotFoundExeption {
        String arg = args[0];
        if (CONSOLE_HANDLER.equals(arg)) {
            System.out.println("Console action...");
            inputHandler = new ConsoleInputHandler();
            initOutputHandler(args, 1);
        } else if (CSV_HANDLER.equals(arg)) {
            System.out.println("Csv action...");
            inputHandler = new CsvInputHandler(args[1]);
            initOutputHandler(args, 2);
        } else if (DATABASE_HANDLER.equals(arg)) {
            System.out.println("Database action...");
            inputHandler = new DatabaseInputHandler(args[1]);
            initOutputHandler(args, 2);
        } else {
            throw new ActionNotFoundExeption();
        }
    }
    
    private void initOutputHandler(
            String[] args, int index) throws ActionNotFoundExeption {
        String actionType = args[index];
        if (CONSOLE_HANDLER.equals(actionType)) {
            outputHandler = new ConsoleOutputHandler();
        } else if (CSV_HANDLER.equals(actionType)) {
            outputHandler = new CsvOutputHandler(args[index + 1]);
        } else if (XML_HANDLER.equals(actionType)) {
            outputHandler = new XmlOutputHandler(args[index + 1]);
        } else if (HTML_HANDLER.equals(actionType)) {
            outputHandler = new HtmlOutputHandler(args[index + 1]);
        } else {
            throw new ActionNotFoundExeption();
        }
    }


Думал, что может быть сделать так:

Код

    private static final String CONSOLE_HANDLER = "-console";
    private static final String CSV_HANDLER = "-csv";
    private static final String DATABASE_HANDLER = "-db";
    private static final String XML_HANDLER = "-xml";
    private static final String HTML_HANDLER = "-html";
    
    private InputHandler inputHandler;
    private OutputHandler outputHandler;
    
    private static Map<String, InputHandler> INPUT_HANDLERS = new HashMap<String, InputHandler>() {
        private static final long serialVersionUID = 1L;

        {
            put(CONSOLE_HANDLER, new ConsoleInputHandler());
            put(CSV_HANDLER, new CsvInputHandler());
            put(DATABASE_HANDLER, new DatabaseInputHandler());
        }
    };

    private static Map<String, OutputHandler> OUTPUT_HANDLERS = new HashMap<String, OutputHandler>() {
        private static final long serialVersionUID = 1L;

        {
            put(CONSOLE_HANDLER, new ConsoleOutputHandler());
            put(CSV_HANDLER, new CsvOutputHandler());
            put(XML_HANDLER, new XmlOutputHandler());
            put(HTML_HANDLER, new HtmlOutputHandler());
        }
    };
    
    private void initHandlers(String[] args) throws ActionNotFoundExeption {
        inputHandler = INPUT_HANDLERS.get(args[0]);
        outputHandler = OUTPUT_HANDLERS.get(args[1]);
    }


Но при условии, что имя файла динамически задаётся входным параметром, то так вроде тоже сделать не получится. Можно конечно сделать в едином для всех классов Handler интерфейсе метод setFileName() и его использовать после получения из мапы определённого Handler класса, но такой вариант мне не нравится тем, что не всегда это нужно - т.е. например в случае ConsoleInputHandler вообще нету файла и инициализировать ничего не надо (т.е. не хочу засовывать в общий интерфейс методы, которые не предназначены для всех классов его имплементящих).

Может у кого-то есть идеи как без лишних извращений решить данную задачу ?
PM MAIL   Вверх
jk1
Дата 7.2.2010, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Как насчет шаблона Chain of Responsibility?

Пусть в роли Handler выступят ваши классы-обработчики. Передаете параметры по цепочке handler'ов и каждый из них сам решает, обрабатывать или передавать дальше.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
RageSteel
  Дата 8.2.2010, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 6.2.2010

Репутация: 1
Всего: 2



Можно воспользоваться enum'ами:

Код

// Отдельно от класса
enum InputHandlerKind {
    console,
    csv,
    db
}

enum OutputHandlerKind {
    console,
    csv,
    xml,
    html
}
// [...]
        private void initHandlers2(String[] args) throws ActionNotFoundExeption {
         List<String> argsList = Arrays.asList(args);
         Iterator<String> argIterator = argsList.iterator();
         String inputKind = argIterator.next();
         inputKind = inputKind.substring(1);
         try {
             switch (InputHandlerKind.valueOf(inputKind)) {
                case console:
                    System.out.println("Console action...");
                    inputHandler = new ConsoleInputHandler();
                    break;
                    
                case csv:
                    System.out.println("Csv action...");
                    inputHandler = new CsvInputHandler(argIterator.next());
                    break;
                
                case db:
                    System.out.println("Database action...");
                    inputHandler = new DatabaseInputHandler(argIterator.next());
                    break;

                default:
                    throw new ActionNotFoundExeption();
                }
     
         } catch (IllegalArgumentException e) {
             throw new ActionNotFoundExeption();
         }
         
         String outputKind = argIterator.next();
         outputKind = outputKind.substring(1);
         try {
             switch (OutputHandlerKind.valueOf(outputKind)) {
             case console:
                 outputHandler = new ConsoleOutputHandler();
                 break;

             case csv:
                 outputHandler = new CsvOutputHandler(argIterator.next());
                 break;

             case html:
                 outputHandler = new HtmlOutputHandler(argIterator.next());
                 break;

             case xml:
                 outputHandler = new XmlOutputHandler(argIterator.next());
                 break;
                 
             default:
                    throw new ActionNotFoundExeption();
                     
             }
         } catch (IllegalArgumentException e) {
             throw new ActionNotFoundExeption();
         }
         
        }


Ну а для более сложных случаев можно воспользоваться apache commons cli.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0664 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.