0

Assuming the following situation:

public interface A {
    void a1();
    void a2();
}

public interface B {
    void b1(A a);
}

public class ImplA implements A {
    // interface methods
    void a1() {};
    void a2() {};
    // ImplA specific methods
    void a3() {};
}

public class ImplB implements B {
    void b1(A a) {
       if(a instaceof ImplA) { // avoid instanceof test and cast 
          ((ImplA)a).a3(); 
       }
    }
}

Would it be possible by some architectural voodoo to avoid an instanceof check in ImplB.b1()? ImplA and ImplB are in the same package and closely related to each other. I read somewhere, that the use of instanceof is a hint for a "no-so-good" interface design. Any recommendations? Thanks alot!

s1ck
  • 158
  • 7
  • 1
    It's hard to say without a lot more context. – Evan Knowles May 08 '14 at 06:39
  • What kind of additional information do you need? – s1ck May 08 '14 at 06:43
  • possible duplicate of [Avoiding instanceof in Java](http://stackoverflow.com/questions/2790144/avoiding-instanceof-in-java) – Raedwald May 08 '14 at 07:00
  • @Raedwald I read this, but I couldn't map the described problem on my case. – s1ck May 08 '14 at 07:34
  • To avoid being closed as a duplicate, you need to explain in your question *why* your question is not actually a duplicate of similar questions. You accepted an answer recommending the Visitor design pattern. Which is also one of the highly voted answers of the [_Avoiding instanceof in Java_](http://stackoverflow.com/questions/2790144/avoiding-instanceof-in-java?lq=1) question. – Raedwald May 08 '14 at 11:28
  • I marked it as solved based on the comment of the author. I unmarked it, if that only relates to the original answer and not the comments. – s1ck May 08 '14 at 11:43

2 Answers2

1

You could use a Visitor pattern to avoid the instanceof cast

public interface Visitor {
    void visitImplA(ImplA toVisit);
}

public class VisitorImpl implements Visitor {

    @Override
    public void visitImplA(ImplA toVisit) {
        toVisit.a3();
    }
}

public interface A {
    void a1();
    void a2();
    void accept(Visitor visitor);
}

public interface B {
    void b1(A a);
}

public class ImplA implements A {
    // interface methods
    void a1() {};
    void a2() {};
    // ImplA specific methods
    void a3() {};

    void accept(Visitor visitor) {
        visitor.visitImplA(this);
    }
}

public class ImplB implements B {
    void b1(A a) {
        a.accept(new VisitorImpl());
    }
}

This would eliminate all you instanceof checks and divide them into the visitor and the implementing classes, this pattern would suffice in the case where you'd be doing the same stuff after most of the instanceof checks, otherwise you'd need a lot of implementations of the Visitor interface

maczikasz
  • 1,113
  • 5
  • 12
  • That sounds reasonable. I will have a deeper look into that. Thanks. – s1ck May 08 '14 at 06:57
  • It seems to me that this pattern is better used, when ImplA and ImplB don't know of each other and the goal is to keep it that way. In my case, they are both closely related to each other (through composition). – s1ck May 08 '14 at 08:06
  • 1
    yeah. Well the easiest way to avoid the instanceof check is to pass an ImplA object in the same place or ad the a3() to the interface, but these are design decisions depending on the context. – maczikasz May 08 '14 at 08:09
1

The VooDoo you want is composition. You can solve that using Visitor dessign pattern. But ther is some penalty when you are using it. Or you can create onther interface that will be used to invoke that a3 method.

The case varry. The reason of question might be that your architecture is not consist and you trying to do something strange or your class perform to many things.

  • how would that additional interface look like, if the current API needs to be unchanged? What do you mean by "not consist". ImplB wants to trigger a state change on ImplA because of an event which is handled by ImplB. – s1ck May 08 '14 at 06:56