ReduxDelphi in action or what can we learn from Redux?
Hi!
In the last time I read many things about Redux, a JS library and architecture style for state management. And I thought that it’s also a good idea for Delphi, because in desktop applications we also have data models and we need to interact with them.
What is redux architecture?
Redux architecture is an “improvement” of MVC: you have an immutable storage that contains the whole data model of your application (or how people that use redux say, state of an application). There is a unidirectional data flow: you press a button, it raises an action that will be sent to your data model which has a dispatcher that creates a new version of your data model via a reducer function and notifies your view about the new version.
Such an architecture will bring some advantages to you:
- Clear separation of data model and view (possible integration with LiveBindings)
- Ease of testing and debugging
- Good concept for multithreaded environment
And disadvantages:
- Every change of your data model fully recreates and copies data and it’s slow
If you want to dive deeper into this style, visit https://redux.js.org/docs/introduction/, the official documentation of JS library.
Immutability
I haven’t read so much about immutability, but my own thoughts brought me to the point that in combination with ARC it really helps in multithreaded applications. Like MVCC, every method/thread/execution unit has its own version of your data model that will never be modified or freed. If you will create a good update procedure then you’ll possibly will always have not the most actual data but without data anomalies or conflicts.
Try Redux out
There is a compact Redux implementation written in Delphi: ReduxDelphi. It’s a fresh, not tested, not ready for production environments library that has memory leaks and isn’t popular, but I was really inspired by that. And here I will introduce you some concepts from Redux with help of this library.
I wrote a sample application that is available on GitHub. It’s a fake news reader that has one story by default:
When you press a second button, you will get the second fake story:
This application was written with ReduxDelphi and I’ll explain which concepts of redux you will find here.
Immutable state
This my “data model” with one class that is stored in immutable list. What does immutable list mean? Actually, this:
Each time you insert an element, you will get a new copy list. It’s like “copy on write” in Delphi strings.
Store
ReduxDelphi also has a store class that has all important methods. I created my own global store:
I will not get into implementation details, but look at the arguments of the constructor: reducer and initial state. The initial state is an immutable list with a first fake story:
Events and dispatch function
My store can dispatch two types of messages defined as TNewsEvent type:
- neRefresh adds the second story to the news list and simulates refreshing an application
- neInit just notifies all observers/subscribers
If you want to send an event to a store, you should call dispatch method:
Reducer
But your storage can’t dispatch events automatically and you also need dispatcher code. Those functions are called reducers. I also have my own reducer:
Reducer will be called by dispatch method and makes changes in a state.
Subscribers
The last important thing in my application is subscribed form that updates every time when state changes.
This is also a very nice feature of storage, because it helps us separate code.
Overall
How does my application work? At the beginning, a store will be created with an initial story about India and after that view will send neInit event to update yourself. Pressing “Refresh” button sends neRefresh event to store and reducer loads the second story about Mexiko into the state, the state sends notification to a form that updates with new version of the store.
So, I will not really recommend to use ReduxDelphi without any improvements, but it’s a good start to look how good storage can be built. There are also other cool frameworks that can help you to deal with events and immutability: Spring4d and DEB. There is also a nice book “MVVM in Delphi” that has some information about usage of observers in applications.
I hope this article will inspire you to create well structured applications :)
That’s all for today :)