Contents


Models

There are lots of definitions of the word Model. We will follow this description: domain model.

In practice, model classes in MVO will mostly contain data and/or logic, they will very likely pass off tasks like network or database access to sub layers, making good use of composition. They typically employ dependency injection techniques to do that, preferably via their constructors. In MVO, the state is located in these models and accessible via quick returning getter methods (usually called by thin views), it’s the state of these models that is the main focus for tests.

You’ll notice that keeping state in models is not a particularly functional pattern, and you’d be right (also neither is dependency injection for what it’s worth). But not writing your UI code in a functional style, actually provides some stunning wins when it comes to Data Binding. MVO says nothing about the code behind the getter methods of the models of course, it can be as functional as you like.

An important thing about these models is that none of the code should know anything about View layer classes. The models are concerned with their data, their logic and their state, and that is all. They don’t know or care what interrogates their state via their getter methods - and this makes our Models extremely easy to test.

“The models are concerned with their data, their logic and their state, and that is all”

In the sample apps, the models are all found in the feature package.

Here’s an example of a model that fetches a session token over a network connection to authenticate a user: Authentication.kt

Writing a Basic Model

If you write a good model, using it in the rest of your app should be a piece of cake.

You’ll see that in all the sample apps, the models have been written with the assumption that all the methods are being accessed on a single thread (which for a live app would be the UI thread). Not having to worry about thread safety here is a very big win in terms of code complexity. The models can use threads and coroutines internally of course.

If you need to pop onto another thread, do it explicitly with something like an AsyncBuilder or launch a coroutine for example, and then pop back on to the UI thread when you are done. The WorkMode.ASYNCHRONOUS parameter will make Observables notify on the UI thread anyway, so you don’t need to do any extra work when you want to update the UI. This is how it’s implemented in java and in kotlin.

ASYNCHRONOUS notifications from an Observable in fore are always sent on the UI thread, no need to do any thread hopping to update the UI

Check out a [few] [examples] from the sample apps, or if you’re already comfortable writing model code (most of this advice applies to writing ViewModels too, so this is all fairly obvious if you are coming from MVVM), feel free to skim over the checklist below for a refresher and you should be good to go.

Model Checklist

For reference here’s a check list of recommendations for the model classes, as used in fore. Once you’ve had a go at writing one you can come back here to double check you have everything down: