Xamarin, Web & Mobile Software Developer/Engineer

Menu

MVVM / MVC is dead? Is Unidirectional a MVVM / MVC Killer?

Ah so now when you’ve learnt MVC/MVVM, everyone’s decided that we shouldn’t do it anymore? Huh?

MVVM is a great pattern which allows for a clean separation between views and logic, it also lends itself well to unit testing, but is it the only way? If you didn’t already know there’s some new kids on the block, Unidirectional User Interface Architectures which is basically applying the CRQS/Event Sourcing pattern on the client side. The idea of these patterns is to have a single DataStore which is the source of truth and data is updated via events, all Views read from the single source of Data and can only update via events/actions. From what I can gather at the moment, the specific problems they solve are 1) Avoid data being duplicated across viewmodels and stale data 2) Avoid the situation of Fat ViewModels. At the moment this concept is being driven from the web clientside world, but eventually it might make it’s way into the Xamarin world and become popular, maybe?

There’s new unidirectional frameworks appearing all the time, the ones I’ve looked into recently are Flux and Redux.

Flux Diagram

Redux Diagram

So can we have these in Xamarin? Yes, these are simply design patterns and can easily be implemented in C#. Infact someone has already created a project based on Redux named Redux.net. In some R&D we’ve been doing on a project we’ve also implemented a Xamarin.Forms sample for the Redux.net project.

Here’s some code from the redux project:

Let’s start with our Application state.

C#

1

2

3

4

5

6

publicclassApplicationState

{

publicImmutableArray<Todo>Todos{get;set;}

publicTodosFilterFilter{get;set;}

}

The Actions are basically any changes in your apps state.

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

publicclassAddTodoAction:IAction

{

publicstringText{get;set;}

}

publicclassDeleteTodoAction:IAction

{

publicGuidTodoId{get;set;}

}

publicclassCompleteTodoAction:IAction

{

publicGuidTodoId{get;set;}

}

publicclassCompleteAllTodosAction:IAction

{

publicboolIsCompleted{get;set;}

}

publicclassClearCompletedTodosAction:IAction

{

}

publicclassFilterTodosAction:IAction

{

publicTodosFilterFilter{get;set;}

}

The application reducer will then take an Action and modify the state.

In all truthfulness I (like most people) don’t know if Unidirectional User Interface Architectures are the answer but I feel like they’re going to be around for a while.

I feel like I’ve hardly done these architectures justice in my explanations but I encourage you to look further into these patterns (maybe even try them or built a Unidirectional Framework for Xamarin). Anyways here’s some links for further reading.

I understand Redux is not about the UI layer directly, and I appreciate the work done on Reducto and Redux.net. However, shouldn’t an additional goal be to construct the UI like React does with its render()-function?

I understand re-rendering the UI is way more complex than the work discussed here, but wouldn’t the ability to render the UI like React be a huge win?

The web browser and native application render differently, both iOS and Android have their own models for rendering. The advantages of react don’t really apply as both iOS and Android already have performant rendering.

I don’t think that this idea is in competition with MVVM exactly. I’ve been doing this for years before it got a name, just to escape weird binding loops, the UI having direct access to data that it shouldn’t have access to, and duplicated state all over the place. First, all user input should trigger commands, and all databinding should be one-way only. The commands should only modify your “one source of truth” that sits below the VMs, and whatever VMs are alive at the moment are all subscribed to to your “one source of truth” and only provide a “filtered view” of it, they don’t actually hold any state.

First of all, I would like to say that I really like what you did with Reducto! Thanks for your comments, I understand better the mind behind Reducto.

IMO, I don’t think one is better than the other. I see Redux.NET and Reducto as two opinionated ports of Redux.js. I never took the time to explain my architectural choices with Redux.NET but maybe here is a good tribune to start :

1. Originally, my colleagues and I combined the reducers in a similar fashion. After a while, we found it more confusing than simple functions composition and switch cases. So I choose to not be opinionated for the structure of reducers and let the consumers build helpers on top of Redux.NET if they want to avoid switch/cast boilerplate. A guy even proposed an F# helper (https://github.com/GuillaumeSalles/redux.NET/issues/23)! At the end of the day, a reducer is just a pure function that takes the previous state and an action, and returns the next state.

My plan is to remove the Rx dependencies (if someone complain about the package size) before 1.0.0 release without breaking changes. (by reimplementing the store as IObservable without Rx)

3. Pretty much like reducers, I think async actions can be built on top of Redux.NET. Unlike Redux.js, I’m still not sure that it should be handled in a middleware (like redux-thunk) because of the static typing nature of C#. At work, we use extension methods on IStore and delegates to create complex action creators. Maybe I’ll add a recipe for that on github if some folks are interested ! I started a simple example of async actions here : https://github.com/GuillaumeSalles/redux.NET/tree/master/examples/async

4. Unfortunately for .NET, I think more developers are going from .NET to javascript than the opposite. So I tried to focus on explaining the concept rather than having the exact same API surface.

5. The name Redux.NET has some downsides… Some of my colleagues thought that Redux.NET was some kind of “artistic” photo album of nude women… http://redux.net/

In any case, I think Reducto and Redux.NET are great tools! I hope the opensource .NET ecosystem will become like the javascript one. A lot of small packages that do a lot of things in a lot of different ways to fulfill a lot of developers needs !

You’re seeing this the wrong angle: Redux is about functional programming (pure functions, DRY, keep sanity checked). You can use Redux even in a ASP.net MVC project. It’s all about DRY, testable functions and simple logic, not about UI!