dimanche 26 mars 2017

Java: Which pattern helps me to implement task properly?

This is what we have at the moment:

interface ReportService {

    Report generate();
  }

and interface implementation:

@Service
public class ReportService_1Impl implements ReportService {

    public Report generate() {

        System.out.println("Report Service 1: generate Report.");
        return new Report();
    }
}

What is the new business requirements for this piece of code:

  • Implement new ReportService_2 that will communicate with the new report engine but new service still have the same generate() method with the same signature;
  • Implement the possibility to switch between these services in Runtime based on some pre-defined configuration;
  • As an option: think about the ability to introduce new ReportServices in the nearest feature.

Okay, let's start to implement all steps that were mentioned above:

Step 1:

new ReportService_2:

@Service
@Qualifier("ReportService_2")
public class ReportService_2Impl implements ReportService {
    public Report generate() {

        System.out.println("Report Service 2: generate Report.");
        return new Report();
    }
}

add @Qualifier("ReportService_1") for ReportService_1Impl

@Service
@Qualifier("ReportService_1")
public class ReportService_1Impl implements ReportService {

    public Report generate() {

        System.out.println("Report Service 1: generate Report.");
        return new Report();
    }
}

Step 2:

How to switch between 2 services in Runtime based on configuration?

Frankly speaking, I am not sure how to implement this task properly, I've just introduced new ReportService that plays the role of Container or Wrapper for ReportService_1Impl and ReportService2_Impl and determines which implementations need to use:

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    @Qualifier("ReportService_1")
    private ReportService reportService_1;
    @Autowired
    @Qualifier("ReportService_2")
    private ReportService reportService_2;

    private ReportService getActiveReportService() {

        return true ? reportService_1 : reportService_2;
    }

    public Report generate() {

        return getActiveReportService().generate();
    }
}

Looks quite ugly, but I believe that we can live with it.

And the last step, where I need to implement the following requirements:

think about the ability to introduce new ReportService's in the nearest feature.

I do not know how to implement this properly because with the current implementation, each time when I will add new ReportService_N I will need to remember, that I definitely need to inject newly created ReportService_Nin ReportServiceImpl and it will look like:

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    @Qualifier("ReportService_1")
    private ReportService reportService_1;
    @Autowired
    @Qualifier("ReportService_2")
    private ReportService reportService_2;
    @Autowired
    @Qualifier("ReportService_3")
    private ReportService reportService_3;
    @Autowired
    @Qualifier("ReportService_4")
    private ReportService reportService_4;
    @Autowired
    @Qualifier("ReportService_N")
    private ReportService reportService_N;

Believe, that this kind of problem was solved multiple times in the past and already defined some pattern that I will need to use.

Can someone give me advice or pattern name that helps me to resolve my problem with the last scenario?

Aucun commentaire:

Enregistrer un commentaire