使用没有toString实现的自动生成的类

时间:2019-05-20 08:43:34

标签: java design-patterns tostring

作为集成的核心服务的一部分,我有一些自动生成的类(模型)。但是,这些类的作者有意/无意地保留了 toString 方法的替代。 我对如何使用这些类有一些选择,对此我需要一些了解。

  1. 我可以在包中覆盖这些类的完全相同的副本,从而覆盖 toString 方法,并在.gitignore中添加这些自动生成的类。但是,使用此方法的注意事项是,这些类中的任何将来更改都不会反映在我的代码中,新开发人员可能会忽略服务和我的实现中的不兼容性。

  2. 我可以为顶级类创建一个包装器类,并添加toString,但是随后我必须为每个方法调用getter,如果它包含嵌套类,则可能导致某种平面图创建。 (混乱的 toString方法)

  3. 我当时正在考虑使用装饰器模式(将功能添加到类中而不破坏它),但是我不确定这是否是打算使用的方式。

我很肯定自己不是第一个遇到此问题的人,因此必须采取某种 正确的方法 来解决该问题。朝这个方向轻推会有所帮助。


编辑
到目前为止,我已经观察到唯一的方法是更改​​字节码或使用反射。但是,更改字节码只会解决受影响的类的问题,而不会影响所有(将来的)类。 相反,我编写了一个实现 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);
    }

0 个答案:

没有答案