Modularity
Monolithic systems have the problem of coupling. Cognizant of this fact, we want to move to a modular system.
What is a Mifos module?
Mifos modules should be carved out based on functional cohesion. There can be a two kinds of modules functional and cross-functional. (For list of modules please check here. http://mifosforge.jira.com/wiki/display/MIFOS/Functional+Modules)
All modules ...
- would be identifiable in the source code as a maven module.
Functional modules...
- would encapsulate the data and behavior for a part of the system.
Cross functional modules...
- can be used as libraries by other modules.
Proposed Module Guidlines
Database/Schema management
- Should module be decoupled from each other to the extent that they can possibly have their own database? Implications: no foreign key relationship, possible independent hosting and deployment, lack of transaction, cannot do joins?
- No. Given Mifos is still seen as one application by its users, creating separate database would be an overkill. Also, there are no performance requirements which would forces us on this route currently.
- Should a module define and manage (provide a version and upgrades) to the portion of the schema that it uses?
- Yes. A module should include sql to create and initialize the portion of the schema that it requires.
Encapsulation
- What the extent of vertical slicing of modules? (i.e. does it include the presentation, action)
A functional module also consists of its own presentation code. The presentation code which delivers data from one or more module need to be handled in a separate mashup module or something like that. - Which layers in a module are accessible to another module at the compile time?
- The service layer would serve as the API for a given module. This could be explicitly enforced using OSGi bundles as well.
- Entities in one module would logically refer to entities in another module. Should these relationships be modeled at the entity level, as well? If not then how would the relationships be created?
- A module should not know about the entities in another module. This means that they cannot be linked together using hibernate relationship. But since there is relationship existing at database level, we should create reference objects and create mapping using it. Reference objects would have only the identifier (no behavior) and they would have immutable (hibernate term for read-only) mapping.
- Which module would host the page when data displayed is from two functional modules?
- Since the functional modules own the presentation of their data. Cross module presentation should be done in a presentation only module. This module depends on functional modules and not vice-versa.
- In case of One-to-One/One-to-Many/Many-to-One (logical) relationships between entities how to decide who refers to whom? How to avoid cyclic relationships between modules?
- If there is no domain relationship between entities in different modules. A parent entity (in module A) has child entity (in module B), when the child entity is created, how does parent entity get the id for it?
- When entities are updated in different modules, would transaction be taken care of? Would it be the case when we use OSGI?
We would spike this when we get to it. - If there is a requirement which involves joining data across different modules. How would we resolve such issues? Where should this code lie? How would we do this using HQL?
We would wait for examples to come up and the discuss it. - Each module potentially has some reference data in it. ReferenceData is something which doesn't change very often. If and when we need it, what should be the caching strategy for reference data?
? - Should each module have their own session factory?
- Should each module have their own session?
Guidelines
A functional module's service/domain-layer wants to read the data owned by another functional module.