2009-09-08 91 views
1

我遇到了这样的问题。类之间的双向1-n关系可以接受吗?

A类有一个B类的列表。A有选择B中的一个,并调用它的方法。所以A取决于B.

但是当一个定时器(不是真正的定时器,只是一个模拟时钟)触发时,B必须告诉A“我已经完成”,所以A可以选择另一个B来工作,这意味着B也必须知道A.

这是一个“双向1-n关系”,我认为A和B没有很好的分离。

当然,我可以使用观察者模式并将A作为观察者,B作为主题,但这不是典型的观察者模式有意义的情况,因为只有一个观察者。

你在想什么?

回答

2

A知道可用Bs。 B只知道目前正在使用他的A。我不认为这是1-n?

但是B不依赖于A,他并不在乎它是A.他只需要使用他的临时助理的“完成()”方法。那里没有真正的依赖。

Class A implements ClientOfB { 
     Collection<B> myBees; 

     public beNottified() { ...} 

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

}

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

我没有看到不合理的依赖性。需要了解buzz和暴露界面。 B只知道界面。

+0

这对我有意义。在调用buzz之后,B可以删除它对A的引用。 – lilyonwind 2009-09-08 19:13:10

1

现在只有一个观察者,但谁知道将来?

A获得B.B公开A(或其他任何人)订阅的事件。 B点燃事件,A获得消息。

乙不知道它只知道它自己的事件。

2

我同意n8wrl一个事件可能是一个更干净的解决方案。

原来的答复:

确实,B就不需要了解所有可能的A或只是把它称为(它告诉一个“我做”)的人吗?如果是这样,那么A可以具有所有B的列表,并且B可以具有仅涉及重要的A的参考。

下面是我该怎么做。是的,这是一种循环关联,但是它对使用方式有一些控制。如果需要,这最终可以重构为纯粹的观察者模式。

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() 
} 
} 
+0

事件只是一个很好的答案,如果他在图书馆或语言本身有抽象。这个问题对语言没有任何假设,所以即使你使用C#,它仍然是一个很好的答案。 – 2009-09-08 19:04:45

+0

此时,B只需要知道打电话的人 - 因为只有A有B的清单,只有A知道下一个要打电话给谁。 我认为这是现在的自然解决方案。这也是我遇到这个问题时遇到的问题。 ---- 也许对A和B使用一些抽象类会使它更清洁。 – lilyonwind 2009-09-08 19:06:09

+0

我正在使用python,所以事件不是选择。 顺便说一句:事件也是观察者模式的实现,至少在C# – lilyonwind 2009-09-08 19:07:24