Я хотел бы знать, как лучше всего обращаться с двунаправленной ассоциацией в 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;
}
}
две проблемы с этой реализации:
- «$ стат e "и" $ cities "должны быть общедоступными (так что каждый может добавить город без использования публичной функции add_city ...). В большинстве языков нет концепции «friend ».
- общественности функция может иметь, чтобы сделать какую-то операцию, прежде чем добавить
РЕАЛИЗАЦИЯ # 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 "который в сусло языке О (п)
ОСУЩЕСТВЛЕНИЯ # 3 (поворот быстрый O (1) операцию в O (N) один.):
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), я бы хотел знать.
EDIT: Если это возможно, я хотел бы решение:
- без использования другого класса
- Не зная порядок, в котором создан объект (т.е. не является решением проблемы «конструктор»)
Вопросы «Вправо» (tm) «вне темы» для Stackoverflow, поскольку они имеют тенденцию генерировать ответы на основе мнения. Просмотрите http://stackoverflow.com/help/on-topic, чтобы узнать, о чем вы должны и не должны спрашивать. –
Простите меня, но я смущен вашей первой реализацией. Почему эти переменные должны быть общедоступными? Класс «friend» мог бы использовать общедоступный метод для другого класса, не так ли? – Jacob
В дополнение к тому, что сказал @TimLewis, возможно, ваш вопрос лучше подходит для [Programmers StackExchange] (http://programmers.stackexchange.com/) :) – Jacob