Let’s say that I have 2 classes: Foo
and Bar
.
`Foo` {
List<Bar> bars
String bippy()
int boop()
}
`Bar` {
int biz()
String baz()
}
Observe that Foo
‘s fields include a List<Bar>
. Note that Foo
has separate fields from Bar
, but they share some fields.
Let’s say that I have a method, f
.
def f(Foo foo) {
...
}
This method, f
, currently accepts only a Foo
type. However, this method also needs access to a Bar
.
When I need to pass in a Bar
, I could simply create a new Foo
with a single Bar
in List<Bar>
– but I don’t like this assumption. Placing this assumption in the code won’t (and should not be) easily understood by the user of it.
So, I decided to create an interface, Something
, that both classes implement:
interface Something {
Optional<String> getBippy()
Optional<int> getBoop()
Optional<int> getBiz()
Optional<String> getBaz()
}
With this interface, I can now update f
‘s argument to be of type Something
.
As a result of this new interface, Foo
‘s and Bar
‘s implementations will return “missing” values if the implementing class fails to have the field expected in the interface.
Example:
Foo implements Something {
List<Bar> bars
getBippy() { return bippy }
getBaz() { return None }
... // remaining implementations
}
This approach will work, I believe, provided that the developer who consumes the f
method passes in the right type.
How’s my approach? In particular, I’m curious if there’s a more type/statically safe approach.
3