Issue
I'd like to avoid instanceof and casting interface to class. I have method with parameter of interface FFF and depending on whether fff is class AAA or TTT I call appropriate private method. In one of these methods I have to call fff.methodSpecificForOnlyOneImplementationOfInterfaceFFF
I have entities:
public interface FFF {
Long getShipperId();
default void updatePermissions(final Permissions permissions) {
...
this.setPermissions(permissions);
}
}
public class AAA implements FFF {
private TTT Window;
public TTT getWindow();
}
public class TTT implements FFF {
}
And I have Service:
public class MyService() {
private Service service; // injected using Spring Boot
public void updatePermissions(FFF fff) {
final SomeClass someVariable;
if (fff instanceof TTT) {
someVariable = Optional.ofNullable(...)
.map(...)
.orElseGet(() -> createDefaultSettings(fff.getShipperId()));
} else {
someVariable= Optional.ofNullable(...)
.map(...)
.orElseGet(() -> returnPermissions(forwardable));
}
fff.updatePermissions(someVariable);
}
private createDefaultSettings(Long id){
final Settings settings= service.getSettings(shipperId);
return new Permissions(settings.getDefault(), false);
}
private returnPermissions(FFF fff) {
AAA aaa= (AAA) fff;
return Optional.ofNullable(aaa.getWindow()) // There is no getWindow() in FFF interface
.map(Window::getPermissions)
.map(...)
.orElseGet(() -> createDefaultSettings(aaa.getShipperId()));
}
How to avoid instanceof and casting AAA aaa= (AAA) fff;? Or maybe that's ok? Maybe there is better solution for it?
Maybe should I add getTimeWindow() method to FFF interface? Then TTT class have to implement this unnecessary for TTT method
Solution
You should use Strategy design pattern.
Encapsulate logic specific to AAA and TTT to the separate classes under the FFF interface.
public interface FFF {
void updatePermission();
SomeVariable getSomeVariable();
}
And then concrete implementations:
public class AAA implements FFF {
public void updatePermission() {
SomeVariable someVariable = getSomeVariable();
// do smth specific for AAA
}
public SomeVariable getSomeVariable() {
return new SomeVariableAAA();
}
}
public class TTT implements FFF {
public void updatePermission() {
SomeVariable someVariable = getSomeVariable();
// do smth specific for TTT
}
public SomeVariable getSomeVariable() {
return new SomeVariableTTT();
}
}
So finally, you are able to replace your if...else with call a method.
public void updatePermission(FFF fff) {
fff.updatePermission();
}
Answered By - Oleg Cherednik
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.