В настоящее время я пытаюсь обратить внимание на Scala с намерением использовать его для моего следующего проекта, который должен иметь дело с DICOM. DICOM имеет довольно широкую спецификацию, которая охватывает более тысячи страниц стандарта. Мое понимание DICOM довольно ограничено, но вкратце DICOM-объекты - IOD (определение информационного объекта) состоят из модулей, а модули - это набор пар атрибутов имени-значения. Это дополнительно осложняется опциональностью некоторых модулей и атрибутов. Например:Scala - Моделирование объектов домена
SimpleImageIOD: {
PatientModule: {
name: String
dateOfBirth: DateTime
}
StudyModule: {
name: String
date: DateTime (optional)
}
SeriesModule: {
name: String
}
ImageModule: {
height: Integer
width: Integer
pixelSize: Double (optional)
}
EquipmentModule: { (optional)
type: String
}
}
Есть тонны модулей, они могут быть составлены в различных комбинациях, образующих разные ИОД. В свою очередь, Scala имеет множество возможностей моделирования со всеми чертами, классами классов, динамическими классами и т. Д. Как бы вы могли моделировать такой домен в Scala? Я совершенно новый для языка, но я думал использовать неизменяемые классы регистра для определения модулей, а затем объединить их в различном IODs и использовать линзы для обновления:
case class Patient(name: String, dateOfBirth: DateTime)
case class Study(name: String, date: Option[DateTime])
case class Series(name: String)
case class Image(height: Integer, width: Integer, pixelSize: Option[Double])
case class Equipment(type: String)
case class SimpleImageIOD(patient: Patient, study: Study, series: Series,
image: Image, equipment: Option[Equipment])
object Patient {
val nameL: Lens[Patient, String] = ...
val dateOfBirthL: Lens[Patient, DateTime] = ...
}
object SimpleImageIOD {
val patientL: Lens[SimpleImageIOD, Patient] = ...
val patientNamel = patientL andThen Patient.nameL
}
Etc и т.д. Что касается линз это может стать проблемой для кодирования всего шаблона - для объективов M x N x L
будет создан объектив для покрытия всего домена для M
IOD, N
и L
. Также опциональность некоторых полей усложняет задачу, по крайней мере, с scalaz-seven
.
Какие существуют другие жизнеспособные подходы, которые согласуются с духом Scala?
Что вы подразумеваете под «гнездовыми линзами»? –
@ak. - Ну, «состари» действительно. Если у вас есть что-то вроде «Long => Patient» и «Patient => SimpleImageIOD», вы можете составить их, чтобы получить «Long => SimpleImageIOD». Вам не нужно строить каждую возможность; вы можете сделать это там, где вы их используете. –
Что касается линз scalaz, вы, вероятно, имеете в виду 'andThen', а не' compose'. Я думаю, что 'compose' применяется к двум объективам' Long => Patient' и 'String => Patient' будет производить объектив, который делает' (Long, String) => Patient'. Но дело не в том, чтобы ловить линзы на шаблоне, верно? –