Decoupling Monolithic Application Module (MIFOS-4305)
Introduction
This page exists to give some background into why MIFOS-4305 needed to happen and gives some description about the structural state of the codebase that resulted from this story.
Background
Spike - Decouple Application Module explains why we wanted to take on this work and that the intention was to simply split apart the big ball of mud module called application into two seperate parts. As a result the intention was to have one extra module called appdomain that would contain everything needed to allow the service facades (application services) to be exposed/releasable within a JAR and have them work.
Result
Whilst splitting out the code from application into appdomain, I ran into a problem with a dependency between application and questionnaire module. Basically the QuestionnaireServiceFacade class was using two services, the interfaces of which were defined in the questionnaire module but their implementations existed in the application module. This was a bit of a problem to completing the work and at this point I wrongly decided that I needed to try to start by decoupling code for one of the services to begin with, the AuditLogService. This resulted in me pulling out code into the abstract-domain and organization modules. It was only the next morning that I realised I didn't need to do that work but that I should instead move the service facade and the two interfaces defined out of questionnaire module and into the appdomain module. I didn't back out the work around abstract-domain or organization as this work will need to be done at some point anyway.
Resultant Mifos code base structure
As a result of the work described above the module structure of mifos is currently broken down like follows (described in build order):
- common
- domain-dto
- testFramework
- serviceInterfaces
- userInterface
- accounting
- questionnaire
- cashflow
- abstract-domain
- organization
- appdomain
- application
common
- project dependencies: NONE
- produces a JAR file
- should contain cross functional infrastructure utilities
- That said, can become a bit of a bucket, throw it in common so module x and y will have access to it....
- could probably be split up further, common-date, common-infrastructure etc
domain-dto
- project dependencies: NONE
- produces a JAR file
- should contain DTO classes that referenced in domain entitiy classes
- e.g. didn't want organisaztion module depending on serviceInterfaces module (where all dtos are currently)
testFramework
- project dependencies: common
- produces a JAR file
serviceInterfaces
- project dependencies: common, domain-dto
- produces a JAR file
- contains interface definitions of all/most service facades (application services) and DTO classes used in service facade signature.
- Key point is that there is no knowledge of any domain concepts
- Introduce as architectural check to ensure now domain concepts leaking into inteface of services and as such leaking into UI.
QUESTION from Vivek: not used anymore? if not then what would it have?
Answer from Keith: At present, this is very much used.
userInterface
- project dependencies: common, serviceInterfaces
- produces a JAR file
- contains freemarker and spring mvc/spring webflow controllers and related UI beans used in user interface
- Key point is that there is no knowledge of any domain concepts and interacts only with layer below serviceInterfaces (service facades or application services)
accounting
- project dependencies: common
- produces a JAR file
- Let Udai describe this in more detail
questionnaire
- project dependencies: serviceInterfaces (but only to reference questionnaire specific DTOs)
- produces a JAR file
cashflow
- project dependencies: common, serviceInterfaces (but only to reference questionnaire specific DTOs)
- produces a JAR file
abstract-domain
- project dependencies: common, domain-dto
- produces a JAR file
- Purpose is really for core domain abstractions that other modules classes depend on
QUESTION from Vivek: it has country, language etc. given that it shouldn't be called abstract-domain. these are reference and configuration data. It also contains cross module domain related things, which seems to be fine.
Answer from Keith: yes your right at present it has classes that are not really 'abstract' concepts and yes some of these are 'reference-data' or 'master-data' classes which can be pulled out into another module called 'reference-data' or whatever. I just didn't go that far in this piece of work.
organization
- project dependencies: common, domain-dto, abstract-domain
- produces a JAR file
- at present contains organization related domain entities, holiday, office, personnel (not their DAOs or domain services etc)
appdomain
- project dependencies: all projects except for application
- produces a JAR file
QUESTION from Vivek: only service facades?
Answer from Keith: no, this is purely a slightly less monolithic module than the previous 'application' one and at present should contain everything needed to implement service interfaces through code in this module or through required dependencies on other modules
application
- project dependencies: all projects
- produces a WAR file
QUESTION from Vivek: not used anymore? if not then what would it have?
Answer from Keith: Its used in that this is still reponsible for creating the WAR file for deployment. It contains all code not needed for service interfaces to be implemented which mostly means legacy struts/ui related code. Once the UI is completely re-written to freemarker/spring mvc/webflow, this module will be very bare and we can concentrate on removing it and having another module responsible for building the deployment artifact.