KUnidirectional
The goal of this sample app is to show how we can implement unidirectional data flow architecture based on Flux and Redux on Android... using Kotlin :wink:
Install / Use
/learn @CesarValiente/KUnidirectionalREADME
KUnidirectional 
A sample app that shows how we can apply unidirectional data flow architecture on Android using Kotlin.
Motivation
This app comes up as a support material for my talk Unidirectional data flow architecture on Android using Kotlin.
Talking about architecture is always tough, so as for support for the talk and slides that I created, I decided to create an app where I show what I explain in the talk/slides, so is easier to understand everything; and getting your hands dirty is always fun!
Slides
The slides of the talk can be found here.
Blog post series
I've written a blog post series explaining the details of this architecture:
Tell me more!
Our approach is based on Redux and Flux from Facebook (that are pretty popular unidirectional data flow approaches on Web), but slightly different, taking things from each one to work on the way we want.
Why the K ? because we use Kotlin as the programming language, apart from being such a nice and enjoyable language, we take advantage of the really great features this language provide us for building our app.
I wanted to keep this app simple enough so we can understand what we want to learn and is important here, that is just unidirectional data flow. Adding libraries that can help us but have their own principles and learning curve could distract us from our real problem here and make, probably, much more difficult to understand it, so for that reason I decided to go without other libraries and implement everything just using Kotlin code; of course we have kotlin libraries that helps us to work with Kotlin on Android, and test libraries to help us when testing, but apart of that, no libraries, just pure Kotlin code :blush:
Requirements
For a much deeper and better understanding of what we are going to explain here with this document and the code, I deeply encourage you to read the official documentation of Flux and Redux before.
What does this app do?
This app is a simple Items list app, where we can create, edit and delete Items. Items are shown in a list where they can be reordered, deleted and set as favorites. In the edit screen, we can create and edit Items, we can change text and color.
Ok, this is a simple app what is the magic here? Every action in the app follows an unidirectional data flow.
When we click on the button to add a new Item and we navigate to the edit item, when we change the Item's color, when we update the item, when we reorder items, etc. everything follows an unidirectional data flow.
Do you want to see first how does this app look and what it does?
Sure! here you have some screenshots that show basically what we can do with the app:

(You can also reorder items but I was not able to take a screenshot during the process :innocent:)
Are you following this approach on a real app?
Yes we do, I work in a small team inside One Note at Microsoft and we are following this architecture on the project that I'm working right now on all platforms :smile:
umm ok, why?
If you are reading this probably you make software, independently of the platform, you make software.<br />
When has been the last time that you have been working on a multi-platform product, with different teams that work on each platform dealing each one of you with the same features, same problems,.. and then.. going to a meeting, talking to a colleague from other team about how they do x and realise that:
- Both of you use completely different languages, and I'm not talking about programming languages, but vocabulary, terms, etc. <br />you sometimes think: "mate, no idea of what you are talking about"
- Both of you are approaching to exactly the same problem in completely different ways.
- Do you want to have a look at my code? yes sure! but here the problem is not that maybe you don't know the programming language, or the framework used, or libraries, is that the architecture of the app, the components, the modules, are completely different than the ones you are used to.
- Bugs, of course, we always have bugs, but hey, we have the same product, just on different platforms and you have completely different bugs on the same features, and when you try to help or ask for help .... we go then to the point 1... and again and again :confounded:
We know it, we know that pain, how it feels, and we wanted to avoid that if possible; we wanted:
- To have a common language, and again, not talking about programming languages, but vocabulary, terms, etc.
- To have a similar way to approach the same problem.
- To have the same structure in all our apps, the same components, the same way to work, at the end, the same architecture.
- To help and be helped!
- To work/help on another platform without the feeling that you really don't know where to start working nor what to do.
Having the same architecture on all our platforms, make our talks between clients amazing, we all are in the same boat, we know how to drive that boat and how to improve it, all of us.
And of course, we take advantage of all of the benefits of an unidirectional data flow architecture, but here the team from Redux explain it much better :wink:
is this code part of a real app?
Nope, this code is inspired by what we do and how we do, but is much simpler, so that's better for educational purposes like we have here :wink:
Architecture of KUnidirectional
I think an image is more valid than 1000 words:

Modules and components
This app has three modules and three main components:
-
App is the module where our views live, it has the components that the user interacts with. <br /> Also contains ControllerView that acts between views and everything else. <br/> If you are used to MVP pattern, they are very similar to presenters, so they help us to decouple the logic of our business from the view/framework.<br /> <br /> We are going to see later the other different components, but basically what the ControllerView does is being subscribed to State changes, creates an Action after the user interacts with the View (the View has a ControllerView), dispatches the action, and later, when it receives a new state, communicate back to its view so the view can react to the new state and render itself.
-
Store is the main module of our app, our business logic resides there. <br/>If you are coming from Clean Architecture, Store is our Domain. The store has several and important components:
- Actions they are simple elements which indicate what we want to do, what we want to achieve. <br />For instance CreateItem is an action, DeleteItem is another action, and so on. <br /> They can have parameters, for instance when we create an item we have to indicate its text and color, when we delete an item we have to indicate its localId so we can delete it, etc. <br /> We have actions grouped as sealed classes so later when we handle them is much easier to do it.
- State this entity has everything that we need to use, is a simple and immutable data structure. <br/> For instance in the list items, we have the items we have to show to the user, in the edit item screen, we have what the current item has, etc.
- Dispatcher is used to dispatch Actions or a new State. <br /> Dispatcher can be implemented in many ways, as a simple function, as a class with a list of subscribers, using external libraries that follow an event/subscriber pattern or others that follow observer pattern, etc. <br />In our approach we wanted to keep the app simple without 3rd party dependencies that make understanding this architecture more complicated, and we have opted for a simple function that lives in the store, so then we can dispatch actions or new states directly from the store just invoking the function.
- Reducers are pure functions that given an action and the current state of the app, apply this action to that state, and generate a completely new state (remember, a state is an immutable object). The logic of what we have to do resides here,
