4

Suppose I have two classes: A with property A.a, B with property B.b.

Some properties in A depend on B.b, but A.a does not depend on B.b.

Some properties in B depend on A.a, but B.b does not depend on A.a.

I would like A to be notified of changes in B.b, and B to be notified of changes in A.a. If I use the standard observer pattern:

public class A implements B.Observer {..}

public class B implements A.Observer {..}

I get a compiler error:

cyclic inheritance involving B (or A).

I realize that this could cause an infinite loop in general, but it doesn't in this case. For example, if A.a changes, A would notify B. But since A.a has no effect on B.b, there is no return notification to A and no cycle.

I appreciate that Java is trying to prevent general problems, but I need to implement this somehow. Any suggestions?

nikis
  • 11,166
  • 2
  • 35
  • 45
NLRicker
  • 170
  • 1
  • 1
  • 8
  • 4
    It looks like you're trying to solve something with inheritance that shouldn't be solved with inheritance. I'd look to using a general notification interface, perhaps like a PropertyChangeListener, but otherwise use composition. – Hovercraft Full Of Eels Apr 28 '15 at 15:58
  • If you remove B.Observer from B, and A.Obseserver from A, this should solve the problem – ControlAltDel Apr 28 '15 at 16:01
  • I am not sure what you mean by `B.Observer` and `A.Observer`. The standard observer pattern has only one `Observer` interface implemented by all observers. – Chetan Kinger Apr 28 '15 at 16:01
  • I need two observer interfaces. One for changes in A.a and the other for changes in B.b. I have found that I can implement this in an application-specific manner without formally declaring observer interfaces (e.g. A uses a method in B to notify it that A.a has changed). I can then remove the"implements" declarations and eliminate the compiler errors. The publish-subscribe approach in the accepted answer is a more general way to accomplish my goal. – NLRicker Apr 28 '15 at 16:53

1 Answers1

2

Use the publish-subscribe pattern where each of your classes is both a publisher and a subscriber.

interface Publisher {
    void addSubscriber(Subscriber sub);
}

interface Subscriber {
    void handle (Object event);
}

class A implements Publisher, Subscriber {...}
class B implements Publisher, Subscriber {...}

If you don't mind using some JavaFX techniques, then you should look into properties and binding which will allow you to something similar to what you already have but this time no compiler errors

smac89
  • 39,374
  • 15
  • 132
  • 179