Всякий раз, когда я сталкиваюсь с ситуацией, когда метод atomic должен обращаться к закрытым частям различных классов, фундаментальная невозможность ООП правильно реализовать такую вещь ИМХО расстраивает меня.
Рассмотрим простой пример: какая-то коллекция должна отслеживать своих участников, а участники должны отслеживать своих владельцев (например, отношения между существами и локациями в игре).Я не вижу идеального способа реализации добавления, удаления и перехода члена в / из коллекции, которая была бы безопасна для ООП.«Меньшее зло», которое я склонен использовать, - это doAction -методы и notify -методы.Таким образом, пример коллекции элементов будет выглядеть следующим образом (в Java):
class Member{
private Collection owner;
// notification methods
public void notifyMoved(Collection to){
owner = to;
}
// action methods
public void moveTo(Collection to){
owner.notifyRemoved(this);
to.notifyAdded(this);
owner = to;
}
}
class Collection{
private List<Member> members;
// notification methods
public void notifyAdded(Member item){
members.add(item);
}
public void notifyRemoved(Memer item){
members.remove(item);
}
// action methods
public void add(Member item){
item.notifyMoved(this);
members.add(item);
}
}
Проблема в том, что существует возможность нарушить согласованность путем непосредственного вызова методов уведомления.Есть ли лучший способ реализовать такие вещи?У C ++ есть друзья, но как насчет Java и ООП в целом?
Редактировать .В Java я могу поместить их в один пакет, но я не хочу делать это только для того, чтобы разрешить доступ к некоторым методам.Мой вопрос носит более общий и теоретический характер: куда следует помещать действия (методы), если они не относятся к одному конкретному классу объектов;и что делать, если такие действия нуждаются в доступе к их частным лицам.
Краткое изложение решений
- Методы уведомления .Уведомитель изменяет внутреннее состояние объекта в соответствии с объявленным изменением среды.Вызов уведомлений вручную представляет собой угрозу для согласованности.
- Средства доступа, зависящие от языка .
- Java : личный доступ к пакету.
- Java : вложенные классы.(например, Collection является внешним, а Member является внутренним).
- C ++ : классы друзей.