0

I have the following situation in my application:

  • I have a service class with 700+ lines
  • The class is responsible for data aggregation from different sources.
  • There is no real signature in the inputs, as I mentioned in the code example.
  • The service will collect the data sequentially and sometimes we should ignore some method based on specific condition.
  • Currently the code become unmaintainable since the logic is growing and become more and more complex.
  • I already have looked into pipeline and Chain of Responsibility design pattern
    • pipeline: I think it will not resolve my issue, since the output from step1 is not necessary to be an input for step2
    • Chain of Responsibility: also this pattern will not fix the issue since the input signature is different.

Could you please suggest away to refactor the code in order to make things clear and maintainable.

public class DataCollector{

    public Report collect(input1){
        Report report = new Report();
        report.setFirstPart(getFirstPart(input1));
        report.setSecondPart(getSecondPart(report.getFirstPart().getInput2()));
        report.setThirdPart(getThirdPart(input1, report.getSecondPart().getInput3()));
        report.setFourthPart(input1, report.getFirstPart().getInput2());
        if( input1 > report.getSecondPart().getInput3()){
            report.setFifthPart(report.getFirstPart().getInput2());
        }
        else{
            report.setSixthPart(input1, report.getSecondPart().getInput3(), report.getThirdPart().getInput4());
        }
        return report;
    }


    public FirstPart getFirstPart(input1){
        ...method logic(retrieve from DB or call service either rest or soap)
    }

    public SecondPart getSecondPart(input2){
        ...method logic(retrieve from DB or call service either rest or soap)
    }

    public ThirdPart getThirdPart(input1, input3){
        ...method logic(retrieve from DB or call service either rest or soap)
    }

    public FourthPart getFourthPart(input1, input2){
        ...method logic(retrieve from DB or call service either rest or soap)
    }

    public FifthPart getFifthPart(input2){
        ...method logic(retrieve from DB or call service either rest or soap)
    }

    public sixthPart getSixthPart(input1, input3, input4){
        ...method logic(retrieve from DB or call service either rest or soap)
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
mzaje18
  • 1
  • 1
  • 3

2 Answers2

0

Given that the way you aggregate the data is not simple or straightforward I would say that there is no silver bullet for your case, other than the Orchestration pattern which is basically what you have with minor adjustments.

Basically, your DataCollector class should be responsible to orchestrate the data collection operation, but it shouldn't do it itself but instead rely on other more specialized classes for each "part" as you call it.

Having said that, I would suggest you keep the collect() method in the DataCollector class but move each (or maybe multiple if it makes sense) of the other methods for data retrieval to their own specialized classes. This way you can simplify DataCollector making it manageable and keep all the remaining complexity in smaller classes as well.

João Dias
  • 16,277
  • 6
  • 33
  • 45
0

I would suggest to have one more layer as data aggregator responsibility, which would collect data from multiple sources. You cannot skip data collection from multiple sources, but you can create a simplified interface in data aggregator layer that would be refer in Data controller that would hide all the complexity within itself. This approach is inspired by Facade Design Pattern.

To reduce complexity in your code, you have to manage your small process with better design so that they can be easily accessible for collection of data.

Sanjay Soni
  • 201
  • 1
  • 13
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 24 '21 at 10:47