https://kotlinlang.org logo
u

ursus

12/03/2019, 4:08 AM
Folks who map domain model down to ui model
a

Anastasia Finogenova

12/03/2019, 4:37 AM
I had the same set up in multiple projects and came to the conclusion it is something that should be avoided. Otherwise you have multiple mappers "to the domain model" and "from the domain model" and possibly create a bunch of redundant objects along the way. So my preference is just not parse all fields from the response if you don't need them and just keep the ones that are used in the app regardless of it is in the logic layer or ui layer.
Same applied to db , also had a separate model for storing in room and separate for UI representation several times and it only made my life more complex, added mapping logic and redundant object creation
u

ursus

12/03/2019, 4:47 AM
well, I think the amout of mapping should match the complexity of the app, I do see advantage if some fields are added to the ui model, better than passign around tuples
so yea I basically need a reverse-map, but that you cannot do statelessly, since you already removed the extra fields
but I see a way of state.domaItems.find { it.id == clickedUiItem.id }
but its weird
s

streetsofboston

12/03/2019, 12:22 PM
I'm of the opinion to translate domain model classes into separate UI model classes. Don't just add or remove a few fields, no inheritance relationship between the two Your domain model models your business or remote data logic closely. Your UI model models your UI very closely. Don't tie them together firmly with inheritance or aggregation. Tie them loosely together using functions (map). A change in either model should be easy to do, without affecting the other.
a

Anastasia Finogenova

12/03/2019, 2:11 PM
Totally agree on no inheritance point, so what about a concern of extensive object creation? @streetsofboston
Especially I faced it when working with local db and if you going to translate back and forth when tapping into the db (In case of a local shopping cart for example) it becomes inefficient very quickly, the same with the sockets and live update scenarios, the data is being updated with writes and reads so much that it leads to performing these translations at almost every user action (a chat app use case for example)
s

streetsofboston

12/03/2019, 2:29 PM
The extensive object creation is less of a concern with the ART runtime and its (new) GC. If you would have a tight loop with thousands and thousands of object creations per second, then yes, it still would be a concern and you may need to use a less elegant objects structure (e.g use inheritance, etc). But for most stuff that you just put onto the UI, that concern is not that great (anymore). If you are worried about too many object creations and performance, measure first and see if it is really a concern.
a

Anastasia Finogenova

12/03/2019, 2:31 PM
I wish we were developing only for the flagship phones ....but I still see many users using not that performing machines especially in the developing markets
Also I feel Google should look back at the performance tips piece of the documentation as it stated that object creation is expensive and no object creation is always better so maybe they could reevaluate what they are saying
s

streetsofboston

12/03/2019, 2:33 PM
Then it may indeed be a concern for you and may need less elegant implementations. Try to measure first on a underpowered phone, though, to see that excessive object creation is an actual concern.
Yeah, Google went as far as saying that it’s better to use `int`s over `enum`s…. that made sense a few years ago for performance reasons, but it always made your code more error prone… They’d need to update that info. Google ‘android art gc improvements’ to get more info on how the garbage collectors have improved over time on Android.
It remains true that object creation is more expensive than no creation, but the difference has become very little….
a

Anastasia Finogenova

12/03/2019, 2:37 PM
I have seen multiple talks on it from DevSummit and IO too if I am not mistaken, but somehow it feels not many are interested in this 🤔 in a way oh it works then I don't need to know more 😆
😀 1
Also even if the machines became more performing the apps became more demanding, so bettering garbage collection and increasing gpu/cpu is not a linear improvement , there is also consideration of how many apps user is running on average and how memory demanding those are on average
I do feel that the improvements that the manufacturers make are only compensating for how demanding the apps are becoming, with ml on device, ar on device and a bunch of other stuff that is coming on device
s

streetsofboston

12/03/2019, 2:47 PM
Improvements in the GC are not just performance wise, it also improved in its design (eg no more ‘stop the world’ garbage collections, generational garbage collection, etc).
a

Anastasia Finogenova

12/03/2019, 2:49 PM
I believe there stop the wold only when it is completely out of memory, but not each time, you actually gave an idea that I need to rewatch that session I am thinking about 😆
u

ursus

12/03/2019, 2:50 PM
I think OP question was how to reverse-map on clicks, rather than 50 objects instantiated every few seconds
💯 1
s

streetsofboston

12/03/2019, 2:50 PM
Sorry, you are correct; I meant, not every GC is a ‘stop-the-world’-gc anymore, especially ones for first-generation objects. But for serious memory issues, it may still happen
👍 1
u

ursus

12/03/2019, 3:02 PM
also @Anastasia Finogenova I think you worry about nothing, I develop ok Nexus 5, its chat app, every new message, new messages list ist emitted, then mapped onto domain objects, and you cannot notice any perf issue, only thing you would notice is if the lists were long, for which you should use pagination, and then binding, i.e. use diffutil
obviously do what makes sense to you, and match the solution to the complexity of the problem, but creating 10s of objects within non-millisecond intervals is nonissue
a

Anastasia Finogenova

12/03/2019, 3:18 PM
Nexus 5 is not a performing device you are right but even if these possible issues may not be manifesting now they may in prod, as when you are developing you are the only app running usually and you usually rebuild the app which basically kills it and relaunches which is triggering gc for it. for the mapping part if you have hard time mapping back in case your objects don't have any unique identifiers as params (like id coming from a db or a barcode number cases etc) I would consider keeping the fields that you can't assign from within the app, like for example if user id is cached and known to your app than you don't have to keep it for the UI model, you can just grab it in the back mapping and so on, so you can either persist it if it is common across the objects or consider keeping the fields that you can't recreate with the reverse mapping
g

ghedeon

12/03/2019, 5:18 PM
@streetsofboston seems like discussion has derailed from original question (nobody was talking about inheritance). What do you think about actual question in the topic? Should he keep extra fields in UI Model, that are not involved in rendering and just being passed back, or having an additional Map between UI and Domain model is preferable?
s

streetsofboston

12/03/2019, 5:23 PM
yeah… it got a little off-track 🙂 I would say the domain model gives the UI model (or creates a UI model) with all the needed information including a future callback (e.g. a future button-click). The UI can just hold on to that, even if it means holding on to data that is not rendered on the screen (e.g. inside a RecyclerView Adapter’s contents). This can be as little as a primary-key or other identifier.
6 Views