首页 > 解决方案 > Best Way to collect complex logging objects during task execution

问题描述

I would like to discuss different ways to collect data that occurs during execution of (a lot) java code, that is not needed to proceed but shall be stored. Additional difficulty in my situation, storing the side Objects needs another object that would otherwise be unneccessary in all the sub methods.

Basically I have one class (TaskExecutor) delegating a coplex task to another component (Delegate). One Object (ImportantObject c) is only necessary to save the side objects (List<Hint>). These hints are not necessary to proceed task execution and are only for logging complex data to my database. But they are linked to this ImportantObject c.

@Component
public class TaskExecutor {

@Autowired
private Delegate delegate;

public void execute() {
        Object a = new Object();
        Object b = new Object();
        ImportantObject c = new ImportantObject(); // only needed to save hints

        Object result = delegate.performTask(a, b);

    }
}

public class Delegate {

    public Object performTask(Object a, Object b) {
        method1(a);
        Object result2 = method2(a);
        Object result3 = method3(a, b, result2);
    
        return result3;
    }

    private void method1(Object a) {
        new Hint();
    }

    private Object method2(Object a) {
        new Hint();
        return new Object();
    }

    private Object method3(Object a, Object b, Object result2) {
        new Hint();
        return new Object();
    }
}

public class DbService {

    public void saveHints(List<Hint> hints, ImportantObject c) {
        // How to call this?
    }
}

What would be a nice codestyle solution for this problem?

Idea 1: Pass object everywhere

Trivial would be passing Object c into the TaskExecution and all its submethods, so I can save a Hint right when it occurs. Would work but I feel like its bad style.

    private Object method3(Object a, Object b, Object result2, ImportantObject c) {
        dbService.saveHint(new Hint(), c);
        return new Object();
    }

Idea 2: Pass List everywhere

I could also pass a list everywhere to collect the Hints. So I would have to only have to bring this list and ImportantObject c together. Also feels like bad coding style.

public class TaskExecution {

    public Object performTask(Object a, Object b) {
        List<Hint> hints = new ArrayList<>();
        method1(a, hints);
        Object result2 = method2(a, hints);
        Object result3 = method3(a, b, result2, hints);
    
        return result3;
    }

Idea 3: Use some cache

I thought about putting the Hints to a cache and read them in the TaskExecutor. However if I don't cache them linked to the instance of ImportantObject c they loose their meaning. I could not determine if an object from cache is linked to my current instance of ImportantObject.

Idea 4: field variable (if no Spring)

If I wouldn't use spring and would always create a new instance of Delegate this would be a solution

public class Delegate {

    private List<Hint> hints = new ArrayList<>();

    // ...
}

But, well... Spring is there for a reason :-)

标签: java

解决方案


推荐阅读