Рассмотрим эту упрощенную область приложения:
- База данных уголовного расследования
-
Person
- кто-то, кто участвует в расследовании -
Report
- это немного информации, которая является частью расследования. - A
Report
ссылается на первичныйPerson
(объект исследования) - A
Report
имеет сообщников, которые вторично связаны (и, безусловно, могут быть первичными в других исследованиях или отчетах - У этих классов есть идентификаторы, которые используются для хранения их в базе данных, поскольку их информация может меняться со временем (например, мы можем найти новые псевдонимы для человека или добавить лиц, представляющих интерес для отчета).
Если они хранятся в какой-то базе данных и я хочу использовать неизменяемые объекты, похоже, проблема в отношении состояния и ссылок.
Предположим, что я изменяю некоторые метаданные о Person
. Поскольку мои объекты Person
неизменяемы, у меня может быть некоторый код:
class Person(
val id:UUID,
val aliases:List[String],
val reports:List[Report]) {
def addAlias(name:String) = new Person(id,name :: aliases,reports)
}
Итак, мой Person
с новым псевдонимом станет новым объектом, также неизменным. Если a Report
относится к этому человеку, но псевдоним был изменен в другом месте в системе, мой Report
теперь относится к "старому" человеку, то есть к человеку без нового псевдонима.
Аналогично, я мог бы:
class Report(val id:UUID, val content:String) {
/** Adding more info to our report */
def updateContent(newContent:String) = new Report(id,newContent)
}
Поскольку эти объекты не знают, кто к ним относится, мне не ясно, как позволить всем "реферерам" знать, что есть новый доступный объект, представляющий самое последнее состояние.
Это можно сделать, если все объекты будут "обновляться" из центрального хранилища данных, а все операции, которые создают новые, обновленные объекты, хранятся в центральном хранилище данных, но это похоже на дрянное повторное использование базового языка. то есть было бы более ясно, чтобы сделать эти "вторичные сохраняемые объекты" изменчивыми. Итак, если я добавлю псевдоним в Person
, все источники ссылок видят новое значение, не делая ничего.
Как это происходит, когда мы хотим избежать изменчивости, или это случай, когда неизменность не помогает?