a bit concern on my pattern(Dependency injection)
Consider the following case:
Dependency injection pattern:
publicinterface A{
void foo(String para1, String para2, String para3, String para4, String para5 );
}
publicclass Bimplements A{
void foo(String para1, String para2, String para3, String para4, String para5 ){
...
}
}
now i have to write a class that the implementation is quite similar to the foo in class B, but with a few logic is added at the beginning line of code in the foo method.
i suppose to inherit it from class B and override the foo function for my use, that is..
publicclass Cextends B{
void foo(String para1, String para2, String para3, String para4, String para5 ){
...// a bit implementation here
super.foo(para1, para2, para3, para4, para5 );
}
}
My function call will be something like the following..
...
Hashtable myHash =new Hashtable();
myHash.put ("BB",new B());
myHash.put ("CC",new C());
...
public myFunction(String key){
.....
// key = "BB" or "CC"
A myObj = (A) myHash.get(key);
myObj.foo(para1, para2, para3, para4, para5);
}
as serveral parameters are passed to foo(), i am afraid if I can make a mistake in the definition of foo method at class C, a hidden bug will be produced. such as :
void foo(String para1, String para2, String para3, String para4, String para5, String para6 )
instead of
void foo(String para1, String para2, String para3, String para4, String para5)
I can prevent this problem in class B because the interface can check for the correctness for me, but class C not. any suggestion to prevent this protential problem?
thanks,
[2686 byte] By [
pp8080a] at [2007-10-3 4:46:20]

unless you can figure out how the compiler can read your mind and "know" that this method is an error, and not just a special method you really want on class C, I'd say it's not possible.%
thanks for your reply. well, seems we cannot do something like the interface/abstract classes did here.I think I might need to search for another pattern in order to prevent this risk....
i have some knowledge of the pattern literature. i don't believe there is such a thing.%
Why can't you just annotate the method on the subclass C with @Overrides? That will ensure the compiler will complain if the annotated method is not actually overriding the method from B
> Why can't you just annotate the method on the
> subclass C with @Overrides? That will
> ensure the compiler will complain if the annotated
> method is not actually overriding the method from
> B
If you know enough to add the annotation, it seems to me that you'd be smart enough to make sure that the method signature was correct.
I think it's less of an issue with capable IDEs. If I have a class C that implements an interface B, IntelliJ will generate all the interface method stubs for me. I wouldn't go to the trouble of a pattern to enforce it.
%
> Why can't you just annotate the method on the
> subclass C with @Overrides? That will
> ensure the compiler will complain if the annotated
> method is not actually overriding the method from
> B
Thanks oxbow_lakes,
my java version is 1.3, so cannot use @Overrides when defining the function.
> If you know enough to add the annotation, it seems
> to me that you'd be smart enough to make sure
> that the method signature was correct.
Thanks duffymo,
It is because other programmers will follow the pattern that I made for the new implementation, that's why I would like to do something more to ensure all stuffs can work correctly .
Overriding vs Overloading
> I think it's less of an issue with capable IDEs.
> If I have a class C that implements an interface B, IntelliJ will generate
> all the interface method stubs for me.
> I wouldn't go to the trouble of a pattern to enforce it.
Actually the compiler would catch it anyway ("C must be declared abstract: it does not implement method m(...) from interface B").
The OP's wish is, how you pointed out, not enforceable strictly speaking (class C extends a non-abstract class B, where method m(p1,...,p5) already exists, no clue that method m2(p1,...,p6) was intended to be an override and not an overload).
Technically IntelliJ or another IDEs might develop a clever diagnosis:
warning: method foo in class C is sus頲iously similar to method foo in class B. Do you intend to override it?... but it would be an annoyance in the majority of cases, where the distinction is intentional. Viewed another way: it might be an option for a compiler to beep against overloading, but I don't think such a feature would get a consensus...
Template Method pattern:
> It is because other programmers will follow the
> pattern that I made for the new implementation,
> that's why I would like to do something more to
> ensure all stuffs can work correctly .
If this is such a common patern that class B is extended, maybe it can be declared abstract. In this case you can use the template method pattern:
abstract class B {
void foo(String para1, String para2, String para3, String para4, String para5 ) {
// call subclass-specific behavior
this.fooSpecific(para1, para2, para3, para4, para5);
// execute generic behavior
...
}
}
public class C extends B {
//Only implement specific behavior, don't bother invoking generic behavior
void fooSpecific(String para1, String para2, String para3, String para4, String para5 ) {
... // your specific code here
}
}
This way the compiler will catch any mistake in the signature of the specific method.
If class B has to remain concrete, you can do the same (and provide a generic implementation of fooSpecific(...) in class B), but the compiler will not catch such mistakes -> almost back to initial situation, except that you now avoid mistakes of forgetting to call super.foo(...) in C.
Unit Testing
Eventually, regardless of the implementation, you should write unit tests to make sure that the correct method is called, of the form:
public class CTest extends TesCase {
B theB;
public void setUp() { this.theB = new C(); }
public testRightFooCalled() {
param1= ...;
...
param5=...;
theB.foo(param1,..,param5);
assert(...); // check that C's foo()'s contract has been honored
}
> If you know enough to add the annotation, it seems to
> me that you'd be smart enough to make sure that the
> method signature was correct.
I suppose you can look at it that way but sometimes it's not readily apparent. If you add a annotation, the compiler will check for you. It's just easier a lot of times and anyone whol looks at the method later gets more information about the design.
If you use the create class dialog in Eclipse and select methods to override, it will insert the annotation for you.
Just test the code. :)Otherwise...the template method seems like a pretty reasonable approach.People always complain that C# makes you write "override" in method signatures that override other methods. This is why!
Yes, of course. Solve the programmer problem in the language design. COBOL, BASIC, anybody?Brian