As an application grows, it becomes harder to maintain. The complexity increases while the value of reusable modules increases. We know that we have got to do something about it before we risk failure.

Design patterns to the rescue!

Complex applications#

complex application is characterised by at least one of these traits:

  • Multiple components in the component tree that display the same piece of the application state
  • Several sources of updates for the application state such as:

— Multiple users interacting at the same time

— Back-end systems that push updated state to the browser in real-time

— Scheduled background tasks

— Proximity sensors or other device sensors

  • Very frequent updating of the application state
  • A large amount of components
  • Components built with many lines of code, reminiscent of the Big Ball of Mud AngularJS controllers of the past
  • A high level of cyclomatic complexity in components — a high concentration of logical branches or async control flows

At the same time, we want an application that is maintainable, testable, scalable and performant.

Complex applications rarely have all of the valuable traits. We cannot avoid all of the complex traits and still meet advanced project requirements, but we can design our application to maximise its valuable traits.

Separation of concerns#

We can think of s_eparation of concerns_ (SoC) as compartmentalisation of our application. We group logic by system concern to be able to focus on a single concern at a time. At the topmost level, separation of concerns is an architectural discipline. In day to day development, it is knowing almost by heart exactly what goes where.

Example of horizontal layers in a modern web application. Figure from my talk “Model-View-Presenter with Angular” (slides).

We can slice our applications vertically, horizontally or both. When slicing vertically, we group software artifacts by feature. When slicing horizontally, we group by software layer. In our applications, we can categorise the software artifacts into these horizontal layers, or system concerns:

Horizontal layerExamplesBusiness logicApplication-specific logic, domain logic, validation rulesPersistenceWebStorage, IndexedDB, WebSQL, HTTP, WebSocket, GraphQL, Firebase, MeteorMessagingWebRTC, WebSocket, Push API, Server-Sent EventsI/OWeb Bluetooth, WebUSB, NFC, camera, microphone, proximity sensor, ambient light sensorPresentationDOM manipulation, event listeners, formattingUser interactionUI behaviour, form validationState managementApplication state management, application-specific events

view raw

web-application-horizontal-layers.csv hosted with ❤ by GitHub

Horizontal layers of a web application.

The same rule can be applied to our Angular components. They should only be concerned with the presentation and user interaction layers. The result is that we loosen the coupling between the moving parts of our systems.

Sure, this process requires a lot of discipline as we are adding additional layers of abstraction, but the end result’s valuable traits make up for this. Keep in mind that we are only creating abstractions that should have been there in the first place.​

#angular #software-architecture #design-patterns #model-view-presenter

Model-View-Presenter with Angular
3.50 GEEK