I have two classes, Foo
and Bar
, and an Algorithm
class that uses both.
class Foo {
void method(Bar bar) {
bar.otherMethod();
...
}
}
class Bar {
void method() {
...
}
void otherMethod() {
...
}
}
class Algorithm {
void run(Foo foo, Bar bar) {
foo.method(bar);
bar.method();
...
}
}
The algorithm part (run
method) is generic, and I want to be able to reuse it in other projects, involving other pairs of classes analogue to Foo
and Bar
, which I know will each have the methods named method
. However, I do not want to put the Bar.otherMethod
at interface level (because it is not a generic functionality that will be needed for other IFoo
and IBar
pairs).
For this reason, I defined two interfaces:
interface IFoo {
void method(IBar bar);
}
and
interface IBar {
void method();
}
and changed the signature of Algorithm.run()
in order to use these interfaces, into
void run(IFoo foo, IBar bar).
The problem is that now, in the Foo
class, I have to make a cast in order to use specific aspects from its associated Bar
class. A similar cast would probably have to be made when I would use another pair of classes (e.g. I might have Foo2
and Bar2
, where in Foo2.method
I would need to cast its IBar
parameter to Bar2
, in order to be able to use specific functionality).
class Foo implements IFoo {
void method(IBar bar) {
(Bar)bar.otherMethod();
...
}
}
In general, this cast is an indicator of bad design. Is there indeed a problem? What would be a better approach for my intention of having a generic Algorithm.run()
method?
Edit:
One relevant aspect is that the Foo
and Bar
implementations in practice will actually come in pairs. At some point I might have other classes, Foo2
and Bar2
, where Foo2.method
does not need to call Bar2.otherMethod
. In this case, the initial Foo
will not be compatible with Bar2
, but I am not interested in such use cases -- could this have been marked through a different design?
Edit2: Changed title and text to better express that I am interested to work with one pair of Foo
and Bar
classes at a time.