From mobile to web development

Héla Ben Khalfallah
9 min readJan 26, 2020

--

From mobile to web, from ASIS to Redux

Introduction

We don’t choose an API or a technology because it’s the most used or the most rated or noted only, we don’t choose an architecture because it’s “the rule” but there are many runtime, real time and real life constraints and challenges that motivate our choice.

In this story, I share :

  • Before web development : how I used to do things and why ?
  • Why ES6+ ?
  • Why React ? Why Redux ? Why Saga ?

Let’s start the trip …

Whatever the platform, the first question to ask : how to organise code in a flexible, maintainable and extendable way ?

The first step is to choose the right architecture.

Personally, the metric that define if I’m on the right way in the choice of the architecture is summarized in this quote:

You should be able to extend the behavior of a system without having to modify that system. — Robert C. Martin —

ASIS

Before Web Development, I started with Mobile Development.

Inside mobile world I faced several constraints :

  • Changing OS APIs.
  • Customers changing specifications.
  • Settings (themes, fonts, colors, languages, assets, …).
  • Backend changing specifications.
Mobile application constraints

Facing to this constraints, how my application can keep the high-performance, stability, conformity to specifications and be easily adjustable?

Mobile Application Criteria
  • High performance : fast (optimal algorithm), minimal memory consumption.
  • Stable : no crash, no bugs, always the same response and the same display for the same input, precautions against “special cases” of its environment, expandable without causing regressions.
  • Complies with : Apple/Android guidelines, UI / UX guidelines and customer requests.
  • Adjustable : easily and quickly expandable.

If I want to classify these constraints, I will get 4 categories :

Constraints Categories

This is why I called my architecture : ASIS.

Why ASIS ?

Using a standard MVC isn’t enough to handle the changing environments and constraints.

MVC architecture loose readability and maintainability each time the application grow.

Therefore, for mobile applications, I decided to make my own customised architecture that I called ASIS.

How ASIS works ?

Each ASIS component will expose a Facade to talk with a specific constraint:

Architecture components

UI Separation of concern :

UI Separation Of Concern

UI Layers is separated into :
- Views.
- ViewControllers.
- Delegate/Protocols/Actions.

UI logic is slightly coupled to UI display via delegate/protocol.

Rules for views :

  • Views use the input data without processing.
  • Views are responsible for display only.
  • This help when customer requests concern only views and their structures: I find easily what I want to change.
  • If the view wants to execute an action, it calls ViewController’s actions. Views delegate logic staff to ViewController.

Rules for ViewController:

  • ViewControllers are splitted by screen.
  • ViewControllers must inherit from CustomViewController from the api-internals package.
  • CustomViewController encapsulates and centralizes communs ViewController processing : managing pop / push / dismiss navigation (if one day navigation “how” changes), displaying alerts, sending emails, displaying loaders, …

APIs :

For each external API, I try to expose (if possible) an internal API Facade.

For example, if I use an external API for date formatting and management, I will create my internal DateUtils that call the external API. My application will communication only with my internal DateUtils.

Why ? If the external API changes, I will change inside the Facade only, others parts consume my Internal API. I protect my application against external impacts and if one day I want to use another external API, changes will be inside one file.

Also my internals APIs package will contains all ‘core’ modules (reusable modules across all applications) in order to make/update a project template generator after.

ASIS APIs

Settings (iOS case) :

The goal of this layer is to make settings easy :

  • Easy to change theme.
  • Easy to add & modify settings (colors, fonts, sizes, urls, constants …).
  • Easy to add a language.
ASIS Settings

Automate UI Settings :

Firstly I created for each atomic component a settings file (plist) :

Settings Plist

I created custom atomic components that will automatically consume that settings :

Custom atomic components are used instead of default atomic components inside code and xib :

For each component on xib file I attribute an accessibility label :

Settings files reference also to language dictionary key :

I used the accessibility label as key to load settings of the component from plist :

By this way, each time I want to change colors, fonts, sizes, labels, I will not search inside my xibs or all my files code but only inside settings and languages files.

I will never need to change my views if a settings had changed.

  • Decoupling between the “settings” part of the UIs and UIs.
  • Easy wrapping of the application with different themes only by changing the properties in the plist files.

Without knowing, I have created what we call actually : Design system (components, settings and automatic theming).

Services Layer :

ASIS Services
Services & Settings Interactions

ViewController are slightly coupled to Backend : if ViewController need data from backend, it dispatch an action or a demand.

To achieve this goal, in iOS I used NotificationCenter (addObserver / post) to dispatch action and Grand Central Dispatch to handle async and multithreading.

If a part need to read Data : it dispatch an action to Readers.

If a part need to change Data : it dispatch an action to Writers.

Repositories (writers & readers) are the only responsible to change / to expose data (single source of truth, shared store).

I have multiple readers and writers each one is responsible for a part of the global application state (a read + writer by backend db model) : Users, Books, Authors, …

If I had to format data before using it inside UI, I will do it inside Data Provider.

If backend communication protocol had changed, my changes will affect only service layer.

ViewController is the molecule that assemble separated pieces to get the complete behavior.

Example :

If the ViewController need UserList from the backend.

  1. ViewController : post notification
NotificationCenter.default.post(name: Notification.Name("UserList"), object: nil)

2. RestfulProvider is registered to NotificationCenter :

NotificationCenter.default.addObserver(self, selector: #selector(userList), name: Notification.Name("UserList"), object: nil)

3. userList selector will call RestfulManager to execute backend Query (dispatch async, dispatch group, parallel, concurrent, …)

4. When RestFulService finish it works, it will update Repositories with received UserList (dispatch an action to Writers) and send an action to ViewController to reload Data (dispatch action to Readers).

post(name: Notification.Name("UserListSuccess"), object: nill)

5. If an error was occurred, RestFulService will notify ViewController with this status :

post(name: Notification.Name("UserListError"), object: error)

6. ViewController is registered to these Notification.

ViewControllers & Services Communication

From ASIS To Redux

Having this mobile background, when moving to web development with React, I tried to make the same thing : what are the constraints and how will my application resolve them ?

Firstly why React ?

I choosed React because it’s the nearest to native mobile development : components, design system, free architecture design (isn’t a framework), no html templating but a JSX (more JS code than html).

Also, as a native developer, performance counts for me and some concepts like virtual dom, life cycle & Fiber are the most important actors behind my orientation.

In addition, I found that the concept of React Functional Component is near to what I have used to do using my ASIS architecture : views display only and never mutate inputs (pure).

From Which JS Version I started ?

I start web development from ES6 for the same reason : nearest to native development (especially swift).

For me, “web development” was started with ES6 and React (JSX).

Before, web is more about “templating” and “JS scripting” rather than purely JS development.

How I organised my web application ?

Firstly, I tried to make my ASIS web version.

I tried to find ASIS’s equivalent pieces :

  • Notification Center
  • Async manager
  • Data Readers and Providers
  • Easy views customizing

After many tries, reading and research, I discovered this Dan Abramov article :

Then I discovered Redux and I found my ASIS’s equivalent pieces.

Notification Center & Data Readers and Writers => Redux (Dispatchers, Store & Reducers).

Async Manager => Redux Saga.

ViewController => Pages (Container)

Views => Components

UI Settings => sass, css, styled components

General Settings => Constants Files (urls, actions, …)

Multi-Languages => Dico

Why Redux Saga ?

I’m fan with APIs that are near to native or vanilla concept : if JS will changes I will get immediately evolutions without any intermediates.

I always use this rule for my logic parts.

I choosed Saga because it’s based on the powerful generators native concept.

Also because Saga had some similar concepts to GCD : compose (group), cancellation, parallel, concurrency, channel, fork, …

Saga is also easy to debug (native generator function) and to test.

Easy to extend : add new service file then add it to Saga Root.

Redux Architecture :

Why Redux ?

For me Redux isn’t only a state manager but an architecture pattern.

I used Redux because it resolves the most of my applications constraints :

  • Flexibility and scalability (we add feature without tears).
  • Separation Of concern.
  • Slight coupling between all layers and parts (dispatching actions).
  • Performance optimisations.

Conclusion

In this story, I shared why I used Redux for my web applications based on my experience and what I have encountered as constraints and challenges : from mobile development to web development.

Redux for me is the most suitable architecture pattern to embraces changes and extending without losing stability of what has been already developed.

Redux is an atom-molecule architecture : Page assemble the complete behavior. The complete Behavior is splitted into several little atoms : services, reducers, settings, & components.

Thank you for reading my story.

You can find me at :

Twitter : https://twitter.com/b_k_hela

Github : https://github.com/helabenkhalfallah

--

--

Héla Ben Khalfallah
Héla Ben Khalfallah

Written by Héla Ben Khalfallah

Hello! I'm Héla Ben Khalfallah. I'm a software engineer with a wealth of experience in web solutions, architecture, frontend, FrontendOps, and leadership.

No responses yet