2

How to Work with Modules: Overview of Modular Architecture

 2 years ago
source link: https://hackernoon.com/how-to-work-with-modules-overview-of-modular-architecture-675735hv
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to Work with Modules: Overview of Modular Architecture

8

@kruglyakSasha Kruglyak

iOS Teck Lead. I work at TRIARE.net

The modular architecture consists of a set of functions that do not directly depend on each other. They just know how to communicate and interact, but it is quite simple to change each structural unit – like in a puzzle. That’s an advantage it has over monoliths.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-nw843o78.jpeg

Let's replace the concept of a piece of the puzzle with a framework. Each separate implemented functionality will be a collection of code for solving a problem integrated into the project as a framework.

What will the structure of a modular project look like?

This is going to be a root project that hosts the dependencies of other projects/frameworks.

In this example, ModularApp is the root project, and CoreModule, NavigationModule, ServerApiModule, and Onboarding are the particles that make up our product.

  • NavigationModule is responsible for navigation and allows access to any stack and flow.

  • CoreModule is initiated at the beginning; it stores all the styles and sets of views that will be used in a project.

  • ServerApiModule is a module for working with Rest API.

  • Onboarding is a module of the feature that is responsible for training the user.

The number of modules and their content may vary in different projects. The first three modules are needed at the start of any project. Therefore, unlike the Onboarding module, they are always used in our projects.

We’ll examine these modules in detail below. But first – a quick tutorial on how to set up your work.

How do you create a module? 5 steps:

1/ Create a project with the “Framework” template.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-wvbk3ocq.png
2/ Deploy the repository where the project will be located.

Arrange the correct access levels for your team. The developer of the module must have an "owner/maintainer” access level. Developers who will use this module in their projects should remain “developers”.

Working with modules is very convenient in teams. Each team member can be responsible for his own module or use a ready-made module previously implemented in another project simply by changing its properties. It’s convenient to always have a person who can conduct a code review and knows the value that this code brings.

Merge to master only after pull request & code review.


mSNwhNjK4jSxeqYsAKCh9nw9MDY2-tucl3o6u.png
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-0bcq3ocb.png
3/ Start developing your code (describing the functionality of the module). Read the detailed examples below.

4/ To evaluate and test the code, create a test project, add your framework, and bring it to the desired level. The folder structure will be as follows (BaseApp V2 is a project where I am testing framework):

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-iqe43o2a.png
5/ After we have filled in our modules with code, it is necessary to describe all the functionality in the read.me file. Basic sections include Structure, How to use, Recommendations.
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-egfn3osv.png

How to add a module to a live project?

The integration of our module into the project can be done via a standard set: Swift Package Manager, Manual .framework, Carthage, CocoaPods. When choosing a provider, it is necessary to consider some factors:

  • Carthage and CocoaPods are for public code;

  • Manual Framework and SPM allow using internal code;

  • Swift Package Manager does not work with @IBDesignable, @IBInspectable objects.

Now that you know how to work with modules let’s explore the stuffing. We’ll show how we coded our NavigationModule, CoreModule, and ServerApiModule.

Types of software modules – examples

1. NavigationModule

NavigationModule has a very simple structure: Navigation Router with a Navigation Module inside, Navigation Controller, and Navigation Module View Controller. Navigation Module can branch into additional Navigation Modules.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-wxhu3ohn.jpeg

All of these parts communicate via NavigationModel, which consists of the initiating View Controller, and functions as a builder of Navigation Controller.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-xiib3oag.png
NavigationRouter operates on the Window level. It impacts the current module and changes the navigation protocol of the whole application.
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-lejz3olr.png
NavigationModule is the object operating on the line of the current navigation. It communicates with NavigationRouter via Delegate and keeps the current Navigation Controller in memory, as well as NavigationModel’s array. If NavigationModel is an isolated case, then linear navigation is built. Otherwise, we create a side-bar or a tab-bar Controller.
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-2vkg3orr.png
As I already mentioned, navigation should remain simple, and modules should be easy to use.

We only need three points for a successful launch:

  • Initialization of the Router on the Window level;

  • Creation of the NavigationModel based on the starting point in navigation;

  • Launch of the NavigationModule through startNavigationModule.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-dplv3o1s.png
Here’s the visualization of the process: the object receives Window level, NavigationModel generates Navigation Controller (in this case, for linear navigation), which, in turn, initializes NavigationModel, and, as a result, the embedded View Controller performs navigation inside the application.
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-ijm93ogq.jpeg
Importantly, there's cross-cutting access across all the levels. It always comes in handy: for example, while working with push alerts, we always know where to display them or how to make changes.

2. CoreModule

This is a very simple CoreModule we created to:

  • Reduce the projects’ time to launch;

  • Create ready-made UI sets;

  • Visualize xib files;

  • Configure the general style of the application.

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-09nl3oi5.png
Let’s take a look at a simple example: ButtonStyleProperties.

We take all the changeable things out into it. Our designers provide a single file in Figma with all the styles and properties used, so that we easily transfer it into the project, and then visualize through xib files how everything will look like on the devices.

3. ServerApiModule

The idea behind this one was to reuse the existing code and try testing DI in our modules.

Making a call is fast and easy:

mSNwhNjK4jSxeqYsAKCh9nw9MDY2-x6q33op2.png
Request is an object including endPoint, Method, parameters, and headers:
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-80in3o0c.png
In practice, our WeatherRequest consists of endPoint, a determined .get Method, query, appid, and the resulting WeatherObject.
mSNwhNjK4jSxeqYsAKCh9nw9MDY2-anjd3o85.jpeg
When designing a module, keep in mind that the internal implementation can be complex or simple, but the use of the module should be easy to understand.

One of the advantages of modularity is that inside we can use any architecture, any third-party libraries, and this will not break our main project. When initializing a project, we know which modules will be used and how they will communicate with each other, so the control point is exactly the place where the module is glued and not its interior.

Learn about other advantages of modular architecture in the next part of our Modular Architecture Overview. Pros and cons, and revelations from our experience – find out if it’s worth it!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK