面向对象的范式问题

Dav*_*nco 8 language-agnostic oop coupling

虽然我已经编程了很长一段时间,但是当涉及耦合对象时,我似乎总是把头撞到墙上,所以我想知道是否有人有任何资源或我可以遵循的黄金规则.

让我举一个小例子,没有特别的语言......

class Person {
    private int personnel_id
    private String first_name;
    private String last_name;
    private int personnel_level;
    //Lab labs[4]; <- Lab(s) the Person works in
}

class Lab {
    private int lab_id;
    private String lab_name;
    //Person[99] personnel; <- Person(s) working in the Lab
}
Run Code Online (Sandbox Code Playgroud)

让我们暂时忽略ctors/setters/getters/dtors并只是实例化一些东西......

Person people = new Person[1500];
Lab labs = new Lab[10];
Run Code Online (Sandbox Code Playgroud)

我的问题是......这里最好的做法是什么......

people["Gordon Freeman"].blewUp((Lab)"Black Mesa");
-> returns T/F
Run Code Online (Sandbox Code Playgroud)

要么...

labs["BlackMesa"].blownUpBy((Person)"Gordon Freeman");
-> returns T/F
Run Code Online (Sandbox Code Playgroud)

或者它甚至不重要:S

我正在研究的现实生活中的例子要复杂得多.每当Person做某事时,每个人都Lab需要得到通知等等,而我只想弄清楚我是否有任何原则可以在这里申请.

Odd*_*ing 3

我的答案是几个现有答案的组合。

这里的本质问题是,这里有一个隐藏的概念。该方法并不是真正谈论实验室对象或人员对象,而是谈论它们之间的关系。(正如 @dacris 和 @vs 所建议的。)

处理这种情况的一种方法是使用双重调度的语言(谢谢@Ken。)

另一种方法是自动生成代码(谢谢@vs.),在这种情况下,任一方向都有可用的方法。

但通常这些解决方案并不实用——为此改变整个语言似乎有点矫枉过正。

不过,自动生成的解决方案为我们提供了见解。这两种技术都应该是合法的。因此您可以手动实现这两种技术。

但是,如果您不想重复自己,这种方法可以清楚地表明任一方向都是合法的。所以不要出太多汗。

如果您正在编写一个系统,其中 Person 对象除了爆炸之外还有其他用途,那么最好将耦合从 Lab 转到 Person(即将方法放在 Lab 对象上),这样 Person 对象就可以在其他地方使用,而无需必须处理 Lab 对象的更改或与爆炸相关的方法。

...反之亦然。如果一个人所做的只是爆炸东西,那么逻辑应该是保持实验室清洁和原始(这对实验室很重要!)