We have an interface:
ObjectMapper.java
public interface ObjectMapper {
<Input, Output> Output map(Input input, Class<Output> outputClass);
}
Sometimes we can't map input so we want to have a possibility to return the type of Optional<Output>
.
"Bad":
Add new method to interface ObjectMapper
:
<Input, Output> Optional<Output> mapOptional(Input input, Class<Output> outputClass);
Now we have to implement it in every class that implements ObjectMapper
, e.g.:
class DozerObjectMapper implements ObjectMapper {
/** 'map' method implementation and some other stuff **/
@Override
public <Input, Output> Optional<Output> mapOptional(Input input, Class<Output> outputClass) {
if (input == null) {
return Optional.empty();
}
return Optional.of(map(input, outputClass));
}
}
"Bad", it depends :-)
Good:
ObjectMapper.java
with OptionalObjectMapper
class called smart
public interface ObjectMapper {
<Input, Output> Output map(Input input, Class<Output> outputClass);
final class OptionalObjectMapper implements ObjectMapper {
private final ObjectMapper mapper;
public OptionalObjectMapper(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public <Input, Output> Output map(Input input, Class<Output> outputClass) {
return mapper.map(input, outputClass);
}
public <Input, Output> Optional<Output> mapOptional(Input input, Class<Output> outputClass) {
if (input == null) {
return Optional.empty();
}
return Optional.of(map(input, outputClass));
}
}
}
DozerObjectMapper
class has not changed.
Usage:
ObjectMapper objectMapper = dozerObjectMapperFactory.mapper();
Optional<Output> output = new ObjectMapper.OptionalObjectMapper(objectMapper).mapOptional(input);
-
Public APIs or a good practice everywhere?
-
Mocking and 'Fake' smart classes
Elegant Objects vol. 1
by Yegor Bugayenko (version 1.3, January 7, 2017)- http://www.yegor256.com/2016/04/26/why-inputstream-design-is-wrong.html - Why InputStream Design Is Wrong