我想知道在O.O.P中处理双向关联的最佳方法。我在Google和SO 上找到了多个解决方案,但每个解决方案似乎都有缺陷。语言无关紧要,但让我们用PHP来说明我的意思:
假设我有一个简单的国家.. [1..n] ..城市协会:
public class State {
public $cities;
public function add_city($city) {}
}
public class City {
public $state;
public function set_state($state) {}
}
实施#1:
public class State {
public $cities;
public function add_city($city) {
$this->cities[] = $city;
$city->state = $this;
}
}
public class City {
public $state;
public function set_state($state) {
$this->state = $state;
$state->cities[] = $state;
}
}
此实现的两个问题是:
实施#2:
public class State {
public $cities;
public function add_city($city) {
$this->cities[] = $city;
if ($city->state != $this) {
$city->set_state($this);
}
}
}
public class City {
public $state;
public function set_state($state) {
$this->state = $state;
if (!in_array($this, $state->cities)) {
$state->add_city($this);
}
}
}
比#1好一点但是“set_state”函数必须调用“in_array”,必须使用的语言为O(n)(将快速O(1)操作转换为O(n)操作。)
实施#3:
public class State {
public $cities;
public function add_city($city, $call_the_other_function = true) {
$this->cities[] = $city;
if ($call_the_other_function) {
$city->set_state($this, false);
}
}
}
public class City {
public $state;
public function set_state($state, $call_the_other_function = true) {
$this->state = $state;
if ($call_the_other_function) {
$state->add_city($this, false);
}
}
}
实施#3是非常有效的,但由于额外的可选参数,它有点“丑陋”(缺乏更好的术语)
无论如何,如果有人知道“正确的方式”(tm)是什么,我想知道。
编辑: 如果可能的话我想要一个解决方案:
答案 0 :(得分:2)
我尝试使用构造函数,这样,当您实例化城市时,您可以直接传递其状态。
public class State {
private $cities;
public function add_city($city) {
$this->cities[] = $city;
}
}
public class City {
private $state;
function __construct($state) {
$state->add_city($this)
$this->state=$state
}
}
答案 1 :(得分:0)
在所有提案中,City都知道State中的方法,反之亦然。如果您引入了负责将城市与州(例如LocationService
)与linkCityToState
等一种方法相关联的第三类,该怎么办?有了这个,您可以稍后使用linkCityToCountry
或某些高级逻辑(例如getPostalCodeFromApi
)对其进行扩展。
如果您担心性能问题,请将列表转换为hashset,这会将查找复杂性降低到O(log n)
。
同样在您的实施#1中,您有city->cities
...?
在任何情况下,除非我编写压缩算法,驱动程序,海量数据库查询等,否则我永远不会使用解决方案#3。