2011-07-25 77 views
1

假设有两个类:ABOO设计问题

A可以在B上操作。

我需要能够查询A已运行的所有B实例。

而对于特定的B实例,我需要能够查询对其进行操作的所有A实例。

这种问题的优雅(在OO口味..)解决方案是什么?

+1

这取决于你使用的是什么语言,但理论上你可以创建某种列表,并且每次发生一个事件被触发,其中A在B上操作,你将添加到该列表中。其他情况也是如此。 – Keelx

+0

听起来像观察员模式给我。如果你使用Java,也许你需要扩展一些类/接口 –

回答

0
import java.util.*; 
class A { 
    void operate(B b) { 
     operatedOn.add(b); 
     b.operatedOnBy.add(this); 
    } 
    final Set<B> operatedOn = new HashSet<B>(); 
} 
class B { 
    final Set<A> operatedOnBy = new HashSet<A>(); 
} 
public class Main { 
    public static void main(String[] args) { 
     A a=new A(); 
     B b=new B(); 
     a.operate(b); 
     System.out.println(a+" "+a.operatedOn); 
     System.out.println(b+" "+b.operatedOnBy); 
    } 
} 
1

像Java我会做类似语言:

package com.whatever.blah; 

public class A { 
    private Set<B> patients = new HashSet<B>; 

    public void operateOn(B patient) { 
     patient.startRecoveringFromOperation(this); 
     patients.add(patient); 
    } 

    public List<B> getPatients() { 
     return patients; 
    } 
} 

public class B { 
    private Set<A> surgeons = new HashSet<A>; 

    //this has package access to `A` can access it but other classes can't 
    void startRecoveringFromOperation(A theSurgeon) { 
     surgeons.add(theSurgeon); 
    } 

    public List<A> getSurgeons() { 
     return surgeons; 
    } 
} 

这个真没有做什么特别的,除了使用package access允许A访问BstartRecoveringFromOperation()方法,而隐藏方法从大多数其他类。在其他语言中,您可能会使用其他方法来完成此操作。例如,在C++中,您可以将A声明为Bfriend

+0

看来你正在复制数据...是最优雅的设计?顺便说一句,我看不到'b'在哪里定义.. –

+0

这样我只能通过'A'实例操作,而不是'B'实例... –

+0

@new_perl - 那个'b'是一个错字,它应该已经'耐心'了(现在已经固定)。我不能说这是否是最优雅的设计,因为这取决于你想要用它完成什么。这只是解决问题的一种可能方案。它确实存储了一些冗余数据,以简化为给定的'B'查找每个'A'的逻辑。是的,这只允许你通过'A'操作'B',因为我认为这是所需的使用模式。如果这不适合你的设计,你当然可以修改它,只要你喜欢。 – aroth