Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to best divide big app into modules?

Building the app I am working on takes a lot of time. Its the biggest one I worked on. I tried to tweak the gradle settings, which is helping, but still the build is quite slow.

Since the app was built without modules in mind, its just a whole lot of packages and now I wonder how I could "extract" some of them and put them into separate modules. AFAIK the modules should not have dependencies to the app module, so I wondered if there is a tool or technique which would allow me to analyse code and help me to find the right packages to extract, since it's a lot of code.

How would you approach my issue?

like image 893
stoefln Avatar asked Jan 09 '18 12:01

stoefln


3 Answers

Your question is Source Code Modularization in Software Engineering. It is new subject in software and there are few references about it. Source Code Modularization is recasting of Clustering concepts on Source Codes.

in this reference from (see reference 1)

The aim of the software modularization process is to partition a software system into subsystems to provide an abstract view of the architecture of the software system, where a subsystem is made up of a set of software artifacts which collaborate with each other to implement a high-level attribute or provide a high-level service for the rest of the software system.

However, for large and complex software systems, the software modularization cannot be done manually, owing to the large number of interactions between different artifacts, and the large size of the source code. Hence, a fully automated or semiautomated tool is needed to perform software modularization.

There are many techniques (Algorithms) to Source Code Modularization (see reference 1):

  1. Hierarchical Techniques:

    • Single Linkage, Complete Linkage, Average Linkage
    • Ward Method, Median Method, Centroid Method
    • Combined and Weighted Combined Methods
  2. Search-Based Techniques:

    • Hill Climbing, Multiple Hill Climbing (HC)
    • Simulated Annealing (SA)
    • Genetic Algorithm (GA)

Notice that you can find other Clustering techniques with this names too. But Modularization is a little different. They are recast to source code modularization.

The overall Source Code Modularization Process shown as below:

enter image description here


There are many tools you can use. You can use them in Modularization Process:

  1. Static Source Code Analysis Tools (to get ADG format and etc.) see the reference here - (like Understand, NDepend and etc.)
  2. Visualization Tools - (Graph Visualization) see the list here (like Tom Sawyer Visualization)

For example of little project, If your project structure (that generated from source code by use of Static Analysis Tools) are like this:

enter image description here

the result can be like this (after applying Modularization Process):

enter image description here

like image 98
Gholamali-Irani Avatar answered Oct 16 '22 22:10

Gholamali-Irani


This is primarily a design problem. As you stated that there is already a large amount of code in the project, one approach would be to analyse the UML diagram for the entire project structure. The goal is to identify regions of the architecture where the interactions are closely coupled between a few classes, groups may also be formed based on which classes have the same external dependencies.

With this approach, you reduce the complexity of the large project, de-coupling classes from external dependencies which they do not use in the large project. The invididual modules which you split the project into will have faster build times. The modules which you split the project into can then be referenced in the main project as dependencies. The additional benefit is that only the modified modules in the main project will be rebuilt each time you make changes.

This Stack Overflow post discusses many UML diagram generator plugins for Android Studio. Code Iris is a good option that you can install via the Android Studio plugin menu. As an example, here is the output from Code Iris on a sample FaceTracker Android application (click on the diagram to enlarge):

enter image description here

The diagram here shows the grouping of packages and projects. You can see that different projects are split into separate green boxes, within these boxes, are boxes for the packages and then finally classes and interactions. By analysing the UML, you can first identify how to best group your classes and create individual projects. Once you split the main project into modules, you can then use Code Iris again to visualise interactions after changes have been made to the structure.

like image 33
sparkplug Avatar answered Oct 16 '22 22:10

sparkplug


I would Divide my application into four layers :

  1. Layer for Objects : in this layer you initiate all the objects that you are in need , with the get and set methods {example:

class person{ region private private int _PersonID; endregion region public public int PersonID{get{return _PersonID;}set{_PersonID=value;}} endregion }}

  1. Layer for Data Access : this layer will handle the contribution of connecting your database and do everything related to procedures, triggers and functions .{this section must be truly protected } {Do not implement any sql queries inside your code , build all your queries into your database and connect those procedure by calling their names in your codes} {example: //

    class personDAO { private List _GetPersons(){//codes here} ; public List GetPersons(){ _GetPersons();} public delegate void del_GetPersons(); private del_GetPersons _del_GetPersons; public del_GetPersons Del_GetPersons { get{return _del_GetPersons;} set {_del_GetPersons=value;} } public personDAO() {//constructor del_GetPersons=GetPersons; } } }

  2. Layer for Business Object , this Layer will delegate instances of the Data access library and than modify it and add with multiple exception handlers . "we use delegates to hide our method names that are used in by equalizing the method to it's delegate into the constructor function of the DataAccessLibrary ". example class personBO { //create instance of personDAO //create an other delegate for personBO //create private method _GetPerson(){//call personDAO.del_GetPersons()} //create public method GetPerson() {// call _GetPerson()} create public constructor function personBO{//set public method = delegates of bo} }

4.Finally there is the final layer or the layer where the user have the privilege to inter-act with , it is a multiple connected forms that are handled via front-end handlers and hidden back-end Handlers (where they are called using delegates too).

  • this structure may take longer in building your application than other

  • but it is fast ( since delegates make it faster)

  • it is protected( since it is devised into many layers and you are dealing with the hidden methods that call an instance of an object not the object itself).

like image 1
Mark Dibeh Avatar answered Oct 16 '22 21:10

Mark Dibeh