Использование автоматически сгенерированных классов без реализации toString - PullRequest
4 голосов
/ 20 мая 2019

У меня есть несколько автоматически сгенерированных классов (моделей) как часть основной службы, которую я интегрирую. Однако авторы этих классов намеренно / непреднамеренно оставили переопределение метода toString . У меня есть несколько вариантов использования этих классов, о которых мне нужно кое-что понять.

  1. Я могу сделать точные копии этих классов в моих пакетах, переопределяя метод toString , и добавить эти автоматически созданные классы в .gitignore. Однако, предостережение при таком подходе заключается в том, что любые будущие изменения в этих классах не будут отражены в моем коде, и новые разработчики могут не заметить несовместимость в службе и моей реализации.

  2. Я могу создать класс-обертку для классов верхнего уровня и добавить toString, но затем мне придется вызывать методы получения для каждого отдельного метода, и если он содержит вложенные классы, которые могут привести к созданию плоской карты. (Хаотический метод toString)

  3. Я думал об использовании шаблона декоратора (добавляя функциональность в класс, не нарушая его), но я не уверен, что именно так он и предназначен.

Я уверен, что я не первый, кто столкнулся с этой проблемой, поэтому должен быть какой-то правильный путь , чтобы заняться этим. Смещение в этом направлении было бы полезно.


EDIT
До сих пор я заметил, что единственный способ - это изменить байт-код или использовать отражение. Тем не менее, изменение байт-кода будет исправлено только для классов, затронутых не для всех (будущих) классов. Вместо этого я написал собственный регистратор, который реализует org.slf4j.Logger и отменяет ведение журнала информационного уровня так, что он:

  • Ведет себя одинаково для всех объектов, имеющих метод toString переопределен

  • Разбирает объект в Json с использованием библиотеки Джексона и объединяет этот Json в строку предоставленный аргумент

Хотя Джексон внутренне использует отражение для преобразования pojo в json, я делаю это только в тех случаях, когда у меня нет myobject.toString ().

Вот реализация моего собственного регистратора.

public class MeinLogger implements Logger {
private static final String REGEX_CURLY = "\\{}";
private static final String TO_STRING = "toString";
private static final String CURLY_ALTERNATE = "REGEX_CURLY";
    private final Logger superLogger;
    private ObjectMapper objectMapper;

    public MeinLogger(Class<?> className) {
        this.objectMapper = new ObjectMapper();
        this.superLogger = LoggerFactory.getLogger(className);
    }

    @Override
    public void info(String s) {

    }

    @Override
    public void info(String s, Object o) {
        boolean toStringImplemented = false;
        try {
            if(checkToStringAndReturn(o).equalsIgnoreCase(CURLY_ALTERNATE))
                toStringImplemented = true;
            s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o));
        } catch (NoSuchMethodException | JsonProcessingException e1) {
            e1.printStackTrace();
        }
        s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
        if(toStringImplemented) {
            superLogger.info(s, o);
        } else {
            superLogger.info(s);
        }

    }

    @Override
    public void info(String s, Object o, Object o1) {
        List<Object> implementedClasses = new ArrayList<>();
        try {
            if(checkToStringAndReturn(o).equalsIgnoreCase(CURLY_ALTERNATE))
                implementedClasses.add(o);
            s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o));
            if(checkToStringAndReturn(o1).equalsIgnoreCase(CURLY_ALTERNATE))
                implementedClasses.add(o1);
            s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o1));
        } catch (NoSuchMethodException | JsonProcessingException e) {
            e.printStackTrace();
        }
        s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
        if(implementedClasses.size() > 0)
            superLogger.info(s, implementedClasses.toArray(new Object[0]));
        else
            superLogger.info(s);
    }

    @Override
    public void info(String s, Object... objects) {
        List<Object> implementedClasses = new ArrayList<>();
        for (Object obj : objects) {
            try {
                if(checkToStringAndReturn(obj).equalsIgnoreCase(CURLY_ALTERNATE))
                    implementedClasses.add(obj);
                s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(obj));
            } catch (NoSuchMethodException | JsonProcessingException e1) {
                e1.printStackTrace();
            }
        }
        s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
        if(implementedClasses.size() > 0)
            superLogger.info(s, implementedClasses.toArray(new Object[0]));
        else
            superLogger.info(s);
    }

...