12

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?

stoefln
  • 14,498
  • 18
  • 79
  • 138
  • Basically, i'd approach it by taking a good look at the current architecture, outlining parts of it into specific modules and start moving things around while keeping it in "still builds and works fine" state. – Shark Jan 09 '18 at 12:50
  • Yes. I can see that this approach makes sense. The problem here is that there are countless packages, so I don't even know where to start. I think my approach of looking for the modules with the least app-dependencies makes sense. But iterating through files, counting dependencies would take me days of repetitive, boring work. Thats why I thought there should be a tool for that. – stoefln Jan 09 '18 at 12:59
  • Noone's stopping you from making one, and I'd be grateful if you do make it :D but as it is... it's a tedious, and very serious refactoring task. – Shark Jan 09 '18 at 15:44
  • How large is the said app? Secondly what makes it large, is it the app's resources and assets, third party libraries or your own code. And lastly why are you uncomfortable with the size? – Niza Siwale Jan 21 '18 at 17:16

3 Answers3

10

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.

sparkitny
  • 1,503
  • 4
  • 18
  • 23
7

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

Gholamali Irani
  • 4,391
  • 6
  • 28
  • 59
1

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).

Mark Dibeh
  • 469
  • 7
  • 21