In a SpringBoot
application I have a service (in the Spring sense) that calls clients that themselves consume RestFul web services by calling a function that is identical to createXXX
except that the nature of the object changes at the input of the method. To simplify, let's suppose that I model the creation of animals: with the objects CatDTO
, DogDTO
, HorseDTO
as input of the web services. AnimaslDTO
is an object composed of different types of animals (there is no inheritance relationship).
I make the three clients in the same manner let's take the cat's example
package com.animals.client;
import ...
@Service
public class CatClient {
private static final String CODE_WS_CREATE_CAT = "createCat";
/**
* Call RestFul WS for Cat Creation
* @param catDTO
*/
public ResponseEntity<String> createCat(CatDTO catDTO)
{
// ... Call a RestFul WS in the same manner for each animal. Only the parameter change in each client
// --> ie dogDTO in DogClient.createDog, HorseDTO in HorseClient.createHorse,
}
}
In AnimalService implemented by AnimalServiceImpl
I try to create the three animals Here is the code
package com.animals.service.impl;
import ...
@Service
public class AnimalServiceImpl implements AnimalService {
@Autowired
private CatClient catClient;
@Autowired
private DogClient dogClient;
@Autowired
private HorseClient horseClient;
@Override
public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
catClient.createCat(animalsDTO.getCat());
dogClient.createDog(animalsDTO.getDog());
horseClient.createHorse(animalsDTO.getHorse());
....
}
}
I want to know how to generify my clients in Spring or Java for the methods which are very similar to createXXX
. What design pattern can I use? What I've tried is to use Java generics but it doesn't fit well with Spring. I've tried to create an AnimalClient(T)
class where T is the animal but I have problems in autowiring constructor with one argument.
Thanks by advance!
Unless you have Inheritance
, you cannot solve this efficiently even if you try to use Generics
Here is one way to simplify your code:
BaseAnimalDto
is a marker interface for now. You can common methods here if you want.
public interface BaseAnimalDTO {
}
CatDTO
public class CatDTO implements BaseAnimalDTO {
// Cat DTO code
}
Create a BaseAnimalClient
as follows
public interface BaseAnimalClient {
ResponseEntity<String> create(BaseAnimalDTO dto);
}
CatClient
looks like this
@Service
public class CatClient implements BaseAnimalClient {
private static final String CODE_WS_CREATE_CAT = "createCat";
@Override
public ResponseEntity<String> create(BaseAnimalDTO dto) {
return null;
}
}
Let's create a universal AnimalClient
like this:
@Service
public class AnimalClient implements BaseAnimalClient {
@Autowired
private CatClient catClient;
@Autowired
private DogClient dogClient;
@Autowired
private HorseClient horseClient;
@Override
public ResponseEntity<String> create(BaseAnimalDTO dto) {
BaseAnimalClient client;
if (dto instanceof CatDTO) {
client = catClient;
} else if (dto instanceof DogDTO) {
client = dogClient;
} else {
client = horseClient;
}
return client.create(dto);
}
}
Now, your AnimalServiceImpl
looks like this
@Service
public class AnimalServiceImpl implements AnimalService {
@Autowired
private AnimalClient animalClient;
@Override
public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
animalClient.create(animalsDTO.getCat());
animalClient.create(animalsDTO.getDog());
animalClient.create(animalsDTO.getHorse());
....
}
}
However, if you can modify your AnimalsDTO
like this:
public class AnimalsDTO {
private List<? extends BaseAnimalDTO> animalDtos;
// getter, setters
}
Then, your AnimalServiceImpl
will be more simplified like this:
@Service
public class AnimalServiceImpl implements AnimalService {
@Autowired
private AnimalClient animalClient;
@Override
public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
for (BaseAnimalDTO animalDTO : animalsDTO.getAnimalDtos()) {
animalClient.create(animalDTO);
}
....
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.