Рассмотрим этот упрощенный домен приложения:
- База данных уголовного розыска
Person
это кто-либо, участвующий в расследовании
Report
- это информация, которая является частью расследования
- A
Report
относится к первичному Person
(предмет расследования)
- A
Report
имеет сообщников, которые являются вторично связанными (и, безусловно, могут быть первичными в других расследованиях или сообщениях
- Эти классы имеют идентификаторы, которые используются для хранения их в базе данных, поскольку их информация может со временем меняться (например, мы можем найти новые псевдонимы для человека или добавить людей, представляющих интерес для отчета)
Домен http://yuml.me/13fc6da0
Если они хранятся в какой-то базе данных и Я хочу использовать неизменяемые объекты, похоже, существует проблема, касающаяся состояния и ссылок.
Предположим, что я изменил некоторые метаданные о 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
с новым псевдонимом становится новым объектом, также неизменным. Если 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
, все источники будут видеть новое значение, ничего не делая.
Как это происходит, когда мы хотим избежать изменчивости, или это случай, когда неизменность не помогает?