2

Not sure what approach to take for design classes.

public interface AuthoringEvent {
   ProcessingResultEvent authoringEvent(Event data);
}

AbstractAuthoringEvent abstract class implements interface

public abstract class AbstractAuthoringEvent implements AuthoringEvent {

   @Override
   public ProcessingResultEvent authoringEvent(Event data) {

       ResponseEntity<Event> resultData = callService(data);
       etc...
   }

   protected abstract ResponseEntity<Event> callService(Event requestData);

}

AuthoringEventIT class extends abstract class

public class AuthoringEventIT extends AbstractAuthoringEvent {

   @Autowired
   private RESTClient restClient;

   protected ResponseEntity<Event> callService(Event requestData) {

     return restClient.callWebServiceWithAction(url, httpPostMethod, requestData, Event.class);
   }

Resource endpoint class

@Autowired
private AuthoringEventIT authoringEventIT;

@PostMapping()
public ResponseEntity<Event> authorEvent(@RequestBody final EventRequest request) {

    ProcessingResultEvent responseData = authoringEventIT.authoringEvent(request);

    return responseData.getProcessedData();
}

l have 2 more same implementations like Event for Venue and Organization model classes. l know l can remove interfaces and do all on abstract classes level which will all concrete classes implement for they own purpose as it on AuthoringEventIT.class, but my question is...

Do these abstract classes really need separate interfaces to implement? Maybe all 3 abstract classes can implement one Authoring interface some kind of generic method, but how to avoid then implementation in concrete class like AuthoringEventIT which extends abstract class and need to implement again interface method which is already implemented in abstract class? Many thanks...

c0der
  • 18,467
  • 6
  • 33
  • 65
Rosa
  • 29
  • 2

1 Answers1

1

In the Spring framework, there is no a problem to have multiple implementations of one interface. It will be not an issue if between the interface and final implementation will be an abstract class.

There are two ways how to solve the conflict in this case:

  • Use @Qualifier and load all implementations to choose one in runtime
  • Use one of @Condition and load one implementation which depends on some condition

In the first case it will be something like this

@Component("authoringEventIT")
public class AuthoringEventIT extends AbstractAuthoringEvent { //code }

@Autowired
@Qualifier("authoringEventIT")
private AuthoringEvent authoringEventIT;
Loniks
  • 489
  • 1
  • 8
  • 19
  • Thanks for answer @Loniks, not sure l understand it...how should inteface looks then or should l remove it? Beacause l have 2 more interfaces like this for other 2 abstract classes implementation. l want to have one interface for 3 abstract classes but avoid implemnet that interface in final implementation because it's already implemented in abstract class? I do not have much experience with generic methods but maybe it's possible public interface Authoring{ T authoring(T data); } – Rosa Dec 23 '18 at 17:15
  • Hi @Rosa You can just build the tree of classes where on top of it will be an interface and on the button will be final implementations with @Component annotations. In case if you want to use generics this is also possible. Since Spring 4.0 it will automatically consider generics as a form of @Qualifier. So one implementation can use one Genetic implementation and other another. Example `@Autowired private AuthoringEvent stringEvent; // Injects the bean with String implementation @Autowired private AuthoringEvent intEvent;`//injects integer implementation – Loniks Dec 23 '18 at 17:28