Common appear Questions in software design
Modeling for DAO/Repository objects
Diff. types of method in Repository:
- Quick list of items (To pull-down menu)
- Facilitate searching
- General listing (with filters)
For 'Quick list of items', better return a simple HashMap (less memory consumption)
For last two question, use 'Criteria' object.
- Projection 'Criteria' object. define fields to be selected
- Selection 'Criteria' object. define constraints
Note, criteria objects is not simply repr. column spec and where spec in query.
Convention for "finders" load ONE, load LIST, check if any, return "count", quick search, complex search Legimate for return empty list Legimate for return null elements Load list for table format (Filters, PagingParameters) Load list for pull down menu Load ONE by 'Primary Key' or other 'Unqiue Key' Check number of record matching criteria How to specify 'criteria': Criteria object or UseCase as method name suffix (or hybrid) Entity lookup(parameters) return ONE record, may be null Entity get(parameters) return ONE record, assuming exists int count(parameters) return assuming exists List<Entity> list(parameters) return assuming exists Map<PrimaryKey,Label> labels(parameters) return assuming exists Rules: Method suffix should not duplicate the meaning expressed in 'parameter list' Example: MailHostListedAlarmDAO.lookup(MailHost mailHost, String ipAddress) MailHostListedAlarmDAO.getActive(Client client, String ipAddress) MailHostListedAlarmDAO.labels() MailHostListedAlarmDAO.labelsWithDisabledSign() MailHostListedAlarmDAO.list(ListFilter filter, PagingState pagingState) MailHostListedAlarmDAO.search(SearchCriteria criteria) One Primary Entity, One Repository For fetching object of other modules. (Like RBL fetch device in Base module) Define special type of Repository: BaseRepository
More thinking on method naming
Logic ----- findAll imply returning List findOne imply returning Object (will return 'null' if needed) loadOne imply returning Object (never return 'null') search imply accept Criteria object or parameter list for searching label imply returning Map<PrimaryKey, Label> Method Name: [Prefix][ExtraLabel][Suffix] Prefix (explained above) Extra Label (extra meaning / contraints of the finder) Suffix (Annotate the parameter meaning) imply returning Object Extra Label should be meaningful (avoid using 'By') findAllDisabled findAllForDistribute findAllWithDefinedAgen findAllCompletedWithin24Hours findAllCompletedWithin24Hours Suffix annotation confusion in parameters: findAllDisabledByIPAddress(String abc) findAllDisabledByEMail(String abc) findAllDisabledByClientAndIPAddress(Client client, String abc) findAllDisabledByClientAndEMail(Client client, String abc) Use 'Suffix' only when. after using 'extra label', same parameter lists exists for diff. method This may refers refactoring (when you add new method whose signature is duplicated)
How to handle Information version control or audit control
Version control and audit control is two diff. concepts.
- In audit, simply logging who make changes (what, who, where, how), AOP can be used.
- In version control, we need to store the 'contents' and 'diff'. I think there is not generic approach for this issue. But, it can be impl using modeling pattern.
How to model information which requires version control: For entity req. version control, define part of information which are subject to version management. That part can form an entity by itself and bound to a 'time spec'
TODO: Use class and object diagrams to illustrate this!!!!
Modularization at the Data / Schema Design Level
Consider the following case, a service management system consists of a few different modules, eg:
- User account and user perference
- Inventory
- Service Provision and Configuration Management
Data managed by each module may need to reference each other.
For example,
Inventory.Item.owner => UserAccount.User ConfigMgmt.Update.equipments => Inventory.Equipment
Some data managed by one module, will be used directly or indirectly by other module.
How to partition the datasources?
Some think, in diff. scenario: Modules run as an integration applications
- - Module interface is merely the API exported by each module. - Can the data of each module store in diff. Schema? - How to handle the reference between data from diff. module - Can use 'View' to handle this? - This approach looks a little bit high copuling among diff. modules
Another is seperating modules (Course grained), module references date of other module will not be enforced via normal DB integrity constraints.) The module API can be impl. using traditional 'POJO', 'Web Services', or 'SLSB'
Is there any better alternatives to address this module.