I have an object with several lists
public class Contribution<T extends MovieRequest> {
private Set<T> elementsToAdd;
private Set<T> elementsToUpdate;
private Set<Integer> numbersToDelete;
}
This object is sent to the method. There I operate on these lists.
public void correctOtherTitle(
final Contribution<OtherTitle> contribution
) throws ResourceNotFoundException {
contribution.getElementsToAdd().forEach(otherTitle -> {
...
});
contribution.getNumbersToDelete().forEach(number -> {
...
});
contribution.getElementsToUpdate().forEach(otherTitleToUpdate -> {
...
});
}
The problem is that there is no need to complete all the lists and some of them may be null. And then throws a NullPointerException exception.
Of course, it is possible to make a condition if, but it does not look aesthetically.
if(contribution.getElementsToAdd() !- null) {
contribution.getElementsToAdd().forEach(otherTitle -> {
...
});
}
It looks fatal. Do you have an idea how to do it better?
To avoid not null check with explicit if , you could change the types of the Contribution class fields to Optional that wrap the actual data :
public class Contribution<T extends MovieRequest> {
private Optional<Set<T>> elementsToAdd;
private Optional<Set<T>> elementsToUpdate;
private Optional<Set<Integer>> numbersToDelete;
}
and adapt getters consequently.
In this way, you could use Optional.ifPresent(Consumer<? super T> consumer) that spares an explicit not null check :
contribution.getElementsToAdd().ifPresent(otherTitle -> {
otherTitle.forEach(m -> ...);
});
It is not necessary very elegant either. However, it reduces code duplication without introducing intermediary variables (that may create side effect).
Getter methods are indeed invoked once.
The problem is that there is no need to complete all the lists and some of them may be null.
I'd argue that you should fix the root problem, rather than work around it. Why can these sets be null? You already have a "safe" way to indicate that there's nothing to add/delete/update - an empty set. So if these sets are under your control (the fact that they are private and you have getters implies this), then you should enforce that invariant.
For example, maybe your Contribution class could look like this:
public class Contribution<T extends MovieRequest> {
private Set<T> elementsToAdd = new HashSet<>();
// ... same for elementsToUpdate / numbersToDelete ...
public Set<T> getElementsToAdd() {
return Collections.ummodifiableSet(elementsToAdd);
}
public void addElementToAdd(T element) {
elementsToAdd.add(element);
}
}
This pattern involves a fair amount of boilerplate. But code generators such as Immutables help a great deal with that.
There is no shortcut to check for not null, but you could implement a constructor on the Contribution class and initialize the sets to empty sets.
Also, if the code matters to you, I may suggest you to invest your efforts in trying to push the logic of the correctOtherTitle function into the Contribution class, because passing and object to a method that manipulates the object smells like an anemic domain.
Related
In a Spring application I tend to take the request body in a controller method and want to pipe it fluently through multiple method calls (returning different types along the way) such as in the following (simplified) example:
public ResponseEntity<FooDto> postFoo(#RequestBody final FooDto requestBody) {
return Optional.of(requestBody) // Optional<FooDto>
.map(mapper::fromDto) // Optional<FooEntity>
.map(service::insertEntity) // Optional<FooEntity>
.map(mapper::fromEntity) // Optional<FooDto>
.map(dto -> ResponseEntity.created(/* ... */).body(dto).build()) // Optional<ResponseEntity<FooDto>>
.orElseThrow(IllegalStateException::new);
}
As you can see I am tempted to apply some FP patterns but the Optional class isn't really suited to do so since the "optionality" implied is artificial and the underlying object of interest should never be empty in the first place. Therefore the final exception won't (hopefully) ever be thrown and alternatively just calling Optional::get isn't really a great option either since Sonarlint complains about an unchecked get call and rightfully so.
Is there any idiomatic way available, maybe even in conjunction with vavr or other FP libraries, to express such a chain of methods better than with such artifical Optional constructs? Otherwise I might have to refrain from doing so and revert back to a classic imperative approach with a dozen of variables.
EDIT: The way I attempt to use Optional easily gets out of hand if working with methods that return Either<ErrorReason, Optional<FooEntity>> which makes this an Optional<Either<ErrorReason, Optional<FooEntity>>> ending up not legible anymore.
The cleanest way to perform what you're looking for is to restore to the imperative style such as:
public ResponseEntity<FooDto> postFoo(final FooDto requestBody) {
final FooEntity fooEntity = fromDto(requestBody);
final FooEntity updatedEntity = insertEntity(fooEntity); // should be void?
final FooDto responseDto = fromEntity(updatedEntity);
return ResponseEntity.created(/* ... */)
.body(responseDto)
.build();
}
I agree with Naman that an imperative style is probably the cleanest way in this case.
If you really really want to do some Optional style like flow you can create your own class
public final class Value<T> {
private final T value;
// Private constructor to force usage of static construction
private Value(T value) {
this.value = value;
}
// Static constructor Optional style
public static <T> Value<T> of(T value) {
return new Value<>(value);
}
public <R> Value<R> map(Function<? super T, ? extends R> mapper) {
return new Value<>(mapper.apply(this.value));
}
// method to unwrap value
public T get() {
return value;
}
}
Then you would use it like
public ResponseEntity<FooDto> postFoo(#RequestBody final FooDto requestBody) {
return Value.of(requestBody) // Value<FooDto>
.map(mapper::fromDto) // Value<FooEntity>
.map(service::insertEntity) // Value<FooEntity>
.map(mapper::fromEntity) // Value<FooDto>
.map(dto -> ResponseEntity.created(/* ... */).body(dto).build()) // Value<ResponseEntity<FooDto>>
.get();
}
Again, I highly discourage this solution and I would just opt for using imperative style.
In an abstract class I have a Predicate field, that is meant to be a combination of an unknown number of other Predicates. Joining the predicates works just fine but I am trying to have some way to know when the predicate has been initialized (or rather, just a way to know if it has or hasn't been initted).
Here is a short example of what I'm talking about:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
I am looking for ways to set initialized to true once (and once only, hence the final. I think I used it right) any of the setLimits have been called (they're overloaded).
I have other setLimits methods, but for the sake of generic code, I don't want to put a initialized at the end of each of the overloaded methods.
So my question is how can I, in a generic way, set the value of initialized after any of the setLimits methods has been called.
My first idea was to try to wrap the setLimits in some generic method which would call the correct overload by the parameter it gets, and then change initialized in that method. But I am not sure if that's a good idea.
Some other idea I got from another question1 was to put the setLimits in some interface or something similar. But I'm not sure how useful that might prove.
So how might this be accomplished?
(Also, if you happen to notice any design problems in this, please tell me because I'm trying to improve in that matter)
There's no need for separate fields:
private Predicate<Double> limits;
private final boolean initialized;
is basically
private Optional<Predicate<Double>> limits = Optional.empty();
if you want initialized to be set to true once limits is set,
provided you can guarantee that none of the setLimits methods can set it to Optional.empty() again. initialized == limits.isPresent().
You can't guarantee that a method is called in the body of an overridden method; in any case, this is a variant of the Call super antipattern.
You can do it like this:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
#Override protected void setFooImpl(Object param) { ... }
}
But it's pretty ugly.
Let's say I have a manufacturing scheduling system, which is made up of four parts:
There are factories that can manufacture a certain type of product and know if they are busy:
interface Factory<ProductType> {
void buildProduct(ProductType product);
boolean isBusy();
}
There is a set of different products, which (among other things) know in which factory they are built:
interface Product<ActualProductType extends Product<ActualProductType>> {
Factory<ActualProductType> getFactory();
}
Then there is an ordering system that can generate requests for products to be built:
interface OrderSystem {
Product<?> getNextProduct();
}
Finally, there's a dispatcher that grabs the orders and maintains a work-queue for each factory:
class Dispatcher {
Map<Factory<?>, Queue<Product<?>>> workQueues
= new HashMap<Factory<?>, Queue<Product<?>>>();
public void addNextOrder(OrderSystem orderSystem) {
Product<?> nextProduct = orderSystem.getNextProduct();
workQueues.get(nextProduct.getFactory()).add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
factory.buildProduct(workQueues.get(factory).poll());
}
}
Disclaimer: This code is merely an example and has several bugs (check if factory exists as a key in workQueues missing, ...) and is highly non-optimal (could iterate over entryset instead of keyset, ...)
Now the question:
The last line in the Dispatcher (factory.buildProduct(workqueues.get(factory).poll());) throws this compile-error:
The method buildProduct(capture#5-of ?) in the type Factory<capture#5-of ?> is not applicable for the arguments (Product<capture#7-of ?>)
I've been racking my brain over how to fix this in a type-safe way, but my Generics-skills have failed me here...
Changing it to the following, for example, doesn't help either:
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy()) {
Product<?> product = workQueues.get(factory).poll();
product.getFactory().buildProduct(product);
}
}
Even though in this case it should be clear that this is ok...
I guess I could add a "buildMe()" function to every Product that calls factory.buildProduct(this), but I have a hard time believing that this should be my most elegant solution.
Any ideas?
EDIT:
A quick example for an implementation of Product and Factory:
class Widget implements Product<Widget> {
public String color;
#Override
public Factory<Widget> getFactory() {
return WidgetFactory.INSTANCE;
}
}
class WidgetFactory implements Factory<Widget> {
static final INSTANCE = new WidgetFactory();
#Override
public void buildProduct(Widget product) {
// Build the widget of the given color (product.color)
}
#Override
public boolean isBusy() {
return false; // It's really quick to make this widget
}
}
Your code is weird.
Your problem is that you are passing A Product<?> to a method which expects a ProductType which is actually T.
Also I have no idea what Product is as you don't mention its definition in the OP.
You need to pass a Product<?> to work. I don't know where you will get it as I can not understand what you are trying to do with your code
Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>();
// factory has the type "Factory of ?"
for (Factory<?> factory: workqueues.keySet())
// the queue is of type "Queue of Product of ?"
Queue<Product<?>> q = workqueues.get(factory);
// thus you put a "Product of ?" into a method that expects a "?"
// the compiler can't do anything with that.
factory.buildProduct(q.poll());
}
Got it! Thanks to meriton who answered this version of the question:
How to replace run-time instanceof check with compile-time generics validation
I need to baby-step the compiler through the product.getFactory().buildProduct(product)-part by doing this in a separate generic function. Here are the changes that I needed to make to the code to get it to work (what a mess):
Be more specific about the OrderSystem:
interface OrderSystem {
<ProductType extends Product<ProductType>> ProductType getNextProduct();
}
Define my own, more strongly typed queue to hold the products:
#SuppressWarnings("serial")
class MyQueue<T extends Product<T>> extends LinkedList<T> {};
And finally, changing the Dispatcher to this beast:
class Dispatcher {
Map<Factory<?>, MyQueue<?>> workQueues = new HashMap<Factory<?>, MyQueue<?>>();
#SuppressWarnings("unchecked")
public <ProductType extends Product<ProductType>> void addNextOrder(OrderSystem orderSystem) {
ProductType nextProduct = orderSystem.getNextProduct();
MyQueue<ProductType> myQueue = (MyQueue<ProductType>) workQueues.get(nextProduct.getFactory());
myQueue.add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
buildProduct(workQueues.get(factory).poll());
}
public <ProductType extends Product<ProductType>> void buildProduct(ProductType product) {
product.getFactory().buildProduct(product);
}
}
Notice all the generic functions, especially the last one. Also notice, that I can NOT inline this function back into my for loop as I did in the original question.
Also note, that the #SuppressWarnings("unchecked") annotation on the addNextOrder() function is needed for the typecast of the queue, not some Product object. Since I only call "add" on this queue, which, after compilation and type-erasure, stores all elements simply as objects, this should not result in any run-time casting exceptions, ever. (Please do correct me if this is wrong!)
There is a part in my java code where I am extending a class from a library which I haven't written.
#override
public Object getPropertyValue(Object id) {
if(id.equals(model.PROPERTY_RENAME))
model.setName((String)value);
else if(id.equals(model.PROPERTY_COLOUR))
model.setColor((Color)value);
}
Now in this case how should I modify this code to make it scalable. There would be many more properties like location, dimension, etc. Now this model is instance of an abstract class AbsModel.
So every class implementing the AbsModel would have different properties. So the class architecture should be there, so that this part of code remains unchanged, no matter how many more model classes I add.
It looks like you want to carry out some operation on the model when this method (getPropertyValue) is called. I would create a Map of id onto the interface ModelOperation defined as follows:
public interface ModelOperation {
void operate(Object value);
}
Then the map would be defines as follows:
map.put(model.PROPERTY_RENAME, new RenameOperation(model));
Your extension class would then look like this:
#Override
public Object getPropertyValue(Object id) {
map.get(id).operate(model);
// etc...
}
For example, RenameOperation would be defined like this:
public class RenameOperation implements ModelOperation {
public RenameOperation(Model model) {
// etc...
}
public void operate(Object value) {
model.setName((String)value);
}
}
This allows you to support as many model operations as you like and means you don't have to change the extension class you have to write. The above is just an outline. You could use generics on the ModelOperation implementations to avoid the cast of the value in each one.
I guess reflection is probably the answer here if you can rely on some naming to help direct you.
It's not going to be nice, but the idea would be that you'd have a method that would reflect on the type and look up the appropriate method. The code belwo
public Object setPropertyValue(Object id) {
String className = id.getClass().getSimpleName();
// Hope that the method is called set<CLASS> and takes a single parameter that is the class
Method method = model.class.getMethod("set" + className, id.getClass());
// Invoke the method (TODO deal with all of the exceptions)
method.invoke(model, id);
}
There are multiple ways of doing this -- though it depends on what do you mean by "scalable" (being able to cope with lots of requests per second or being able to cope with lots of properties?):
one way -- if you're going to go down the path you have outlined in your code is to have those properties that are used very often at the top of your if/then/else block -- so their execution path is very short. this would "scale up" well for lots of requests as not too much time is being spent in actually executing the method (in most cases at least!)
another way -- and this scales up well for lots of properties and easiness of maintaining the code but you will take a hit on execution time: have a Map that maps property names to setxxx() method names, then you can use reflection to invoke these methods on the target object (id in your case) on each call. Classes extended your class will only have to provide a getMap() method which will return the mapping name-to-setter method, which can be a static member and initialized on class load.
Store your properties in a Map -- in which case setName() is the same as map.put( PROPERTY_RENAME, value)
Since in Java functions are not first class citizens, the "nice" route would be very awkward: define an enum with one value per each constant above (i.e. for each property), and a virtual method e.g. update(Object value, then override the method in each enum to update the corresponding property. If you can, redefine the constants PROPERTY_RENAME etc. themselves as enums. This still results in code bloat.
The other way is to use reflection. If you can use the same ids as the property names you want to update, you only need to invoke the setter for the property (as illustrated in other answers). Otherwise you may need to introduce a mapping from ids to property names.
A version not using reflection, call the base class's implementation:
public Object getValue(Object id) {
Object ret = super.getValue(id);
if (ret == null) {
// Subclass specific properties
}
return ret;
}
A common way around this is to use reflection like
public Object getValue(IdType id) {
Method getter = model.getClass().getMethod("get" + id);
return getter.invoke(model); // throws Exceptions.
}
OR
public void setValue(IdType id, Object value) {
Method setter = model.getClass().getMethod("set" + id, value.getClass());
setter.invoke(model, value); // throws Exceptions.
}
I solved this issue by creating an interface. So the code is.
public interface IModel
{
public void setProperty(String propertyName);
}
Rest of the classes were
public class HelloModel implements IModel
{
public void setProperty(String propertyName)
{ code for handling the properties goes here ... }
}
So in this case every class has to handle it's own property setters.
Is this the best way to handle abstraction ? I think this model is very scalable ...
Sorry for the poor title, can't think of a succinct way of putting this..
I'm thinking of having a list of objects that will all be of a specific interface. Each of these objects may then implement further interfaces, but there is no guarantee which object will implement which. However, in a single loop, I wish to be able to call the methods of whatever their further sub-type may be.
Ie, 3 interfaces:
public interface IAnimal { ... }
public interface IEggLayer { public Egg layEgg(); }
public interface IMammal { public void sweat(); }
this would then be stored as
private List<IAnimal> animals= new ArrayList<IAnimal>();
so, instances added to the list could possibly also be of type IEggLayer or IMammal, which have completely unrelated methods.
My initial instinct would be to then do
for(IAnimal animal : animals) {
if(animal instanceof IEggLayer) {
egg = ((IEggLayer)animal).layEgg();
}
if(animal instance of IMammal) {
((IMammal)animal).sweat();
}
}
But I have always been told that type checking is a sign that the code should really be refactored.
Since it could be possible for a single object to do both [platypus, for example], meaning that a single doFunction() would not be suitable here, is it possible to avoid using type checking in this case, or is this an instance where type checking is classed as acceptable?
Is there possibly a design pattern catered to this?
I apologise for the contrived example as well...
[Ignore any syntax errors, please - it's only intended to be Java-like pseudocode]
I've added lvalue to the EggLayer use, to show that sometimes the return type is important
Clearly your IAnimal interface (or some extension thereof) needs a callAllMethods method that each implementer of the interface can code to polymorphically perform this task -- seems the only OO-sound approach!
But I have always been told that type checking is a sign that the code should really be refactored.
It is a sign that either class hierarchy or the code that uses it may need to be refactored or restructured. But often there will be no refactoring / restructuring that avoids the problem.
In this case, where you have methods that apply only to specific subtypes, the most promising refactor would be to have separate lists for the animals that are egg layers and the animals that sweat.
But if you cannot do that, you will need to do some type checking. Even the isEggLayer() / isMammal() involves a type check; e.g.
if (x.isEggLayer()) {
((IEggLayer) x).layEgg(); // type cast is required.
}
I suppose that you could hide the type check via an asEggLayer() method; e.g.
public IEggLayer asEggLayer() {
return ((IEggLayer) this);
}
or
// Not recommended ...
public IEggLayer asEggLayer() {
return (this instanceof IEggLayer) ? ((IEggLayer) this) : null;
}
But there is always a typecheck happening, and the possibility that it will fail. Furthermore, all of these attempts to hide the type checking entail adding "knowledge" of the subtypes to the supertype interface, which means that it needs to be changed as new subtypes are added.
in C#, you should be able to do this transparently.
foreach(IEggLayer egglayer in animals) {
egglayer.layEgg();
}
foreach(IMammal mammal in animals) {
mammal.sweat();
}
I think the way to think about this question is: What is the loop doing? The loop has a purpose and is trying to do something with those objects. That something can have a method on the IAnimal interface, and the implementations can sweat or lay eggs as needed.
In terms of your issue with the return value, you will be returning null, nothing you can do about that if you share the methods. It is not worth casting within a loop to avoid an extra return null; to satisfy the compiler. You can, however, make it more explicit using generics:
public interface IAnimal<R> {
public R generalMethod();
}
public interface IEggLayer extends IAnimal<Egg> {
public Egg generalMethod(); //not necessary, but the point is it works.
}
public interface IMammal extends IAnimal<Void> {
public Void generalMethod();
}
From your comment where you care about the return type, you can get the return type and dispatch it to a factory method which examines the type and returns something generic that is sublcassed to the specific type and act on that.
Why not have methods added to isAnimal:
public interface IAnimal {
bool isEggLayer();
bool isMammal();
}
Then you can loop through and just query this boolean each time.
Update:
If this was drawing an animal, then having a class that is completely enclosed is reasonable, you just call drawVehicle and it draws a corvette, cessna, motorcycle, whatever.
But, this seems to have a non-OOP architecture, so if the architecture of the application can't change then, since my original answer isn't well received, then it would seem that AOP would be the best choice.
If you put an annotation on each class, you can have
#IsEggLayer
#IsMammal
public class Platypus() implements EggLayer, Mammal {
...
}
This would then enable you to create aspects that pull out all the egglayers and do whatever operations need to be done.
You can also inject into the animal interfaces any additional classes to get this idea to work.
I will need to think about where to go from here, but I have a feeling this may be the best solution, if a redesign can't be done.
There are many ways of going about this. Exaclty which is most appropriate depends upon your context. I am going to suggest introducing an additional layer of indirection. This solves most problems. I prefer designs which avoid multiple inheritance of interface (if I were president of a language, I would forbid it).
I don't think layEggsOrSweatOrDoBothIfYoureWeirdOrNoneIfYouCant() is a great method to polute Animal with. So instead of adding each Animal directly to animals, wrap each in an individual wrapper. I say "wrapper" as a generic name - the random operation we are trying to perform doesn't make any sense.
private final List<AnimalWrapper> animals =
new ArrayList<AnimalWrapper>();
public void doStuff() {
for (AnimalWrapper animal : animals) {
animal.doStuff();
}
}
Then we need some way of adding the wrappers. Something like:
public void addPlatypus(final Platypus platypus) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
platypus.sweat();
platypus.layEgg();
}});
}
If you try to write these wrappers without enough context you get into trouble. These require that the correct one is selected at call site. It could be done by overloading, but that has dangers.
/*** Poor context -> trouble ***/
public void addNormalMamal(final Mamal mamal) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
mamal.sweat();
}});
}
public void addNormalEggLayer(final EggLayer eggLayer) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
eggLayer.layEgg();
}});
}
public <T extends Mamal & EggLayer> void addMamalEggLayer(final T animal) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
animal.sweat();
animal.layEgg();
}});
}