1. Java / Говнокод #16555

    +118

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    if (operator instanceof TUOperatorStacker) {
    	dump.put("operator_type", "TUOperatorStacker");
    } else if (operator instanceof TUOperatorDestacker) {
    	dump.put("operator_type", "TUOperatorDestacker");
    } else if (operator instanceof TUOperatorTargetedStacker) {
    	dump.put("operator_type", "TUOperatorTargetedStacker");
    } else if (operator instanceof TUOperatorTargetedDestacker) {
    	dump.put("operator_type", "TUOperatorTargetedDestacker");
    }
    
    
    
    <...>
    
    
    
    String typeString = (String) dump.get("operator_type");
    TUOperator operator = null;
    
    if (typeString.equals("TUOperatorStacker")) {
    	operator = new TUOperatorStacker(simElement);
    } else if (typeString.equals("TUOperatorDestacker")) {
    	operator = new TUOperatorDestacker(simElement);
    } else if (typeString.equals("TUOperatorTargetedStacker")) {
    	operator = new TUOperatorTargetedStacker(simElement);
    } else if (typeString.equals("TUOperatorTargetedDestacker")) {
    	operator = new TUOperatorTargetedDestacker(simElement);
    }

    Запостил: someone, 18 Августа 2014

    Комментарии (15) RSS

    • Из пустого в порожнее
      Ответить
      • Это разные функции. Там самопальная и довольно кривая сериализация. Одна функция дампит состояние объекта в Map, другая восстанавливает.

        Думаю, как бы написать красивее. Рефлексией, что ли? Или, может, guice + multibindings + assistedinject?
        Ответить
        • ну что бездумно проходит в голову - вынести серилизацию в интерфейс, и реализовать в данных классах, а потом просто дергать методы интерфейса.
          Ответить
          • Это да, а создавать-то экземпляр нужного класса как? Там полиморфизм не пройдёт.

            (Записывать полное имя класса и дёргать конструктор рефлексией нельзя - обратная совместимость-с.)
            Ответить
            • хм. Ну тут в голову приходит фабрика, в коде она и есть, но можно и подумать.

              Как минимум стоки можно заменить какими нибудь ID.

              А что не так с обратной совместимостью? я немного туплю
              Ответить
              • > А что не так с обратной совместимостью?
                Видимо, уже существует куча сериализованных данных, не хранящих полного имени.
                Ответить
                • так мапу можно сделать старых имен и нужных.
                  Ответить
              • Нужна обратная совместимость с документами, сохранёнными в старой версии. Кстати, все четыре класса - потомки одного базового класса, так что общий метод сериализации можно объявить в нём и даже реализовать как return getClass().getSimpleName().

                Пока мне приходят на ум три решения:

                1. Поскольку все четыре класса лежат в одном пакете, использовать имя пакета (определяя его по базовому классу) и прибавлять к нему имя класса
                2. Сделать Map<String, Class> и через рефлексию находить конструктор.
                3. Самый продвинутый вариант - использовать guice-assistedinject с фабричным интерфейсом и получать нужный класс через Names.named.
                Ответить
                • а можно и конвертор написать из старого формата в новой и не страдать. Хотя нужен будет и обратный...
                  Ответить
                  • Никто там не будет писать новый формат. Ни заказчику, ни пользователям это не нужно. Кроме того, проблем с говнокодом это не решит. Сейчас в проекте сотни классов с restore(HashMap<String, Object>) для открытия говноформата, а будут сотни классов с тем же restore(HashMap<String, Object>), только они будут использоваться для конвертации в новый формат.

                    Кстати, там есть ещё совсем старый формат, очень хрупкий - использует стандартную жабью сериализацию.
                    Ответить
                    • >>проекте сотни классов с restore(HashMap<String, Object>)

                      эээ, зачнем? Одному классу дилегировал сериализацию и не мучаешься. Какой нибудь SerializeManager. Зацепление вырастет
                      Ответить
                      • Там каждый класс отвечает за собственную сериализацию в HashMap<String, Object>, который потом пишется в XML.

                        Писалось это в начале нулевых.
                        Ответить
                • http://pollservice.ru/p/cm69uc8cte

                  Я за второй вариант. Нафиг к такой маленькой проблеме городить десяток говноабстракций? К тому же, симметрично: был один костыль, а стало два.
                  Ответить
            • > а создавать-то экземпляр нужного класса как?

              Для каждого класса создаём по (де)сериалайзеру, упаковывающему/распаковывающему объект. Регистрируем их в мапе объекта-фабрики на соответствующие текстовые ключи. При записи объекта выгребаем сериалайзер по типу, при чтении - десериалайзер по магической строке.

              Вроде ничего лучше пока не придумано :(
              Ответить
    • Шаблон "Фабрика" во всей красе. Не издевайтесь, покажите человеку java.util.Map.
      Ответить

    Добавить комментарий