Próbuję uprościć proces sprawdzania poprawności w celu obsługi odpowiedzi na żądania HTTP w Sprayu (używam Slicka do dostępu do bazy danych). Obecnie sprawdzam w jednym zapytaniu, czy powinienem przejść dalej do następującego zapytania, czy nie (błąd powrotu). Kończy się to z dopasowaniem do zagnieżdżonych wzorców. Każdy przypadek sprawdzania poprawności może zwrócić inny błąd, więc nie mogę użyć żadnej płaskiej mapy.Scala - unikaj zbyt skomplikowanych wzorców zagnieżdżonych pasujących do
class LocationDao {
val db = DbProvider.db
// Database tables
val devices = Devices.devices
val locations = Locations.locations
val programs = Programs.programs
val accessTokens = AccessTokens.accessTokens
def loginDevice(deviceSerialNumber: String, login: String, password: String): Either[Error, LocationResponse] = {
try {
db withSession { implicit session =>
val deviceRowOption = devices.filter(d => d.serialNumber === deviceSerialNumber).map(d => (d.id, d.currentLocationId.?, d.serialNumber.?)).firstOption
deviceRowOption match {
case Some(deviceRow) => {
val locationRowOption = locations.filter(l => l.id === deviceRow._2.getOrElse(0L) && l.login === login && l.password === password).firstOption
locationRowOption match {
case Some(locationRow) => {
val programRowOption = programs.filter(p => p.id === locationRow.programId).firstOption
programRowOption match {
case Some(programRow) => {
val program = Program(programRow.name, programRow.logo, programRow.moneyLevel, programRow.pointsForLevel,
programRow.description, programRow.rules, programRow.dailyCustomerScansLimit)
val locationData = LocationData(program)
val locationResponse = LocationResponse("access_token", System.currentTimeMillis(), locationData)
Right(locationResponse)
}
case None => Left(ProgramNotExistError)
}
}
case None => Left(IncorrectLoginOrPasswordError)
}
}
case None => Left(DeviceNotExistError)
}
}
} catch {
case ex: SQLException =>
Left(DatabaseError)
}
}
}
Jaki jest dobry sposób na uproszczenie tego? Może jest inne podejście ..
Twój przykładowy kod jest zbyt szczegółowy w stosunku do tego, co robisz, staraj się być bardziej ogólny. Ale na twoje pytanie, jeśli zmienisz swoje metody xxxRowOption, aby zwrócić 'Albo" będziesz w stanie użyć do zrozumienia. – Maxim
Użyj a, aby zrozumieć. –
Przebudowałem ten kod ze zrozumieniem. Dzięki. – piobab