I have a persistent actor which holds some values. I need to get some filtered ones of them. So, I have two ways:
1) Create new message say
GetValuesWithNameAndAgeGraterThan(name: String, age: Int)
pro: immutable, orthodox :) contra: the problem here is that logic leaks into persistent actor which should be responsible only for keeping and providing data and ya, this case is exactly fits to providing data definition. But why should it know about "name" and "age" of value it keeps?! And since tomorrow I would be needed to add more and more messages which would become a mess at the end.
2) Create generic message with filtering predicate
Filter(p: Value => Boolean)
pro: single, scalable, immutable when used properly contra: I see the only problem when someone does
val ages: mutable.Seq[Int]
persistor ? Filter(v => ages.contains(v.age))
ages += 18
ages += 33
but we are usually using immutable values in Scala! and also it would be unnatural to try to persist lambda, but we use it for read only!
So, what do you think?!
Never do follow the second approach! The first is valid, but id change this a little bit. You could initially agree on some contract for stored data, e.g might be an Enumeration where each value carries a value type. So you modify your message with
GetValueForCondition(conditions: Seq[DataType, filter: Value => Boolean])
, where DataType is an Enumeration value specifying the name and type of data and the filter defines the condition on the value.
This way you can specify generic queries for entities, which is reusable for requests to other data storing actors. You could also include a Boolean indicating for each data field whether it has to be set for an entity to be returned in the result. In case you store all those information belonging to one entity (e.g name, age,...) in an Entity object (e.g your persistent actor has some storage for multiple such Entities), you could implement the filtering generically within that Entity class, and ur data providing actor is free of this logic.