tags:

views:

91

answers:

3

I met a problem like this.

class A have a list of class B. A have choose one of B, and call its method. So A depends on B.

But when a timer ( not a real timer, just a mimic clock ) fires, B have to tell A that "I am done", so A can choose another B to work, which means B has to know A also.

This is a "two way 1-n relationship" and I think A and B are not well seperated.

Of course I can use Observer Pattern and make A an observer and B a subject, but this is not a typical case where observer pattern make sense because there is only one observer.

What do u think about it?

+1  A: 

There is only one observer NOW, but who knows in the future?

A gets a B. B exposes an event that A (or anyone else for that matter) subscribes to. B fires the event, A gets the message.

B does not know about A it only knows about its own event.

n8wrl
+2  A: 

I agree with n8wrl that an event is probably a cleaner solution.

Original answer:

Does B need to know about all possible A's or just the one that called it (the one it tells "I am Done")? If so, then A can have the list of All B's, and B can have a reference to only the one A that matters.

Here's how I'd do it. Yes there's a cyclic association, but there's some control in how it's used. And this can eventually be refactored to a purer observer pattern if required.

class A
{
  List<B> bObj = new List<B>();

  public void callB(/*Params*/)
  {
    B bThatMatters = //Find Appropriate B ...
    bThatMatters.DoStuff(this);
  }

  public void isDone()
  {
     //Handle being done with the last B
  }
}

class B
{
   A _callerA;

   public void DoStuff(A callerA)
   {
      _callerA = callerA;

     //... DO STUFF
   }

 public void WhenDone()
 {
    _callerA.isDone()
 }
}
chocojosh
An event is only a good answer if he has that abstraction in a library or the language itself. The question makes no assumption about language so even though you used C# it's still a good answer.
Samuel Danielson
At this moment, B only needs to know the one who calls it -- because only A have the list of B and only A know which one to call next.I think this is the natural solution now. That's also what came to my mine when I met this problem.----Maybe use some abstract class for A and B will make it cleaner.
lilyonwind
I am using python, so event is not choice.BTW : event is also an implementation of observer pattern, at least in C#
lilyonwind
And one thing makes me skeptic to observer pattern (and event) is that it makes a lot of cylic reference. For example, when I need to drop A, I have to first go over list of B and remove all their reference to A.I think C# now support weak reference when make event binding, but when I worked with C#, I have to remove all these cylce references by hand.
lilyonwind
Thanks, I've been working in C# for the past few months so I had forgotten that not all languages support events.Observer is useful when you need it. In this case, you don't need it, so why have the extra complexity?
chocojosh
+1  A: 

A knows about the available Bs. B only knows about the A currently using him. I don't think that's 1-n is it?

But B doesn't depend upon A as such, he does not care it's an A. He just needs to use the "finished()" method of his temprary associate. There's no real dependency there.

Class A implements ClientOfB {
       Collection<B> myBees;

       public beNottified() { ...}

       public employeeBee () {
             myBees.getRandomBee().buzz(this);
       }

}

Class B {
    public void buzz(ClientOfB client) {
          client.beNotified();
    }
}

I don't see unreasonable dependencies. A needs to know about buzz and to expose an interface. B only knows about the interface.

djna
This makes sense to me. B could remove it's reference to A after buzz is called.
lilyonwind