Let's suppose that I have an interface Stuff
like this:
public interface Stuff {
Long getId();
String getName();
}
and I have implemented this interface as StuffEntity
:
@Entity
public class StuffEntity implements Stuff {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
protected String name;
// constructors, getters (implement interface methods), setters, ...
}
and I have a service interface StuffService
:
public interface StuffService {
Page<Stuff> getStuff(Pageable pageable);
}
implemented as StuffServiceImpl
:
@Service
public class StuffServiceImpl implements StuffService {
@Autowired
private StuffEntityRepository repository;
@Overrride
public Page<Stuff> getStuff(Pageable pageable) {
Page<StuffEntity> stuffEntityPage = repository.findAll(pageable);
return new PageImpl<>(stuffEntityPage.getContent().stream()
.map(Stuff.class::cast)
.collect(
Collectors.toList()),
stuffEntityPage.getPageable(),
stuffEntityPage.getTotalElements()
);
}
I don't like casting here and creating new instance of PageImpl
, so I tried something like this:
public interface StuffService {
Page<? extends Stuff> getStuff(Pageable pageable);
}
@Service
public class StuffServiceImpl implements StuffService {
@Autowired
private StuffEntityRepository repository;
@Overrride
public Page<? extends Stuff> getStuff(Pageable pageable) {
return repository.findAll(pageable);
}
As I've already said, I don't like casting and creating new PageImpl
instance in my service class, but I like how my code looks cleaner that way. The other approach does not need casting or creating new PageImpl
instance in my service class, but I am little worried about service's client side, because now I return wildcard instead of an interface.
Which approach do you think is better?