We have two very similar modules in our MVC project - one for reports and one for exports. Just to explain our nomenclature - exports is only used to generate flat files, and reports is only used to display data in the GUI and to generate PDF files via the GUI.
These modules are distinct in the code, but a lot of the logic and some parts of the models are the similar. For example both the report and export models have a
Field class containing properties such as the name of the field and the type of the field, and both the export and report models have a
Filter class with properties such as the filter's unique name, the label accompanying the filter in the GUI, etc.
The two modules were written by different people - myself and a co-worker. Some model classes are literally identical (the
Filter class is one such class) but others are similar but have necessary differences. For example, the
Field class in the exports model has the
Width property to store the maximum allowable number of characters in fixed width export, however the
Field class in the reports model does not have this
Width property because there is no such thing as a fixed width field in a report. Conversely, the
Field class in the reports model has a property called
Grouping to indicate whether this field is used for group-aggregations in the resulting report, whereas this is not applicable in our exports.
Hopefully from this you get the picture - two models with similar classes. In addition some of the logic is similar between the two modules also. For example filters are received from the GUI and processed in the same way for both exports and reports. This is the exception rather than the rule though - most of the logic is different since ultimately the modules perform different tasks.
So now we have a few different options:
- Keep both modules entirely separate - this is how the code currently is. All code is distinct (except for the functionality that is common to all modules in the project, such as getting data from the database, user authentication, type-manipulations, etc, but such code is not the topic of this question).
- Reference bits of one module from the other. For example, we both might use the
Filterclass as defined in the export model and delete the
Filterclass from the reports model.
- Create a new model (eg
ExportsAndReports.cs) to contain only the bits of the model that can be shared between exports and reports (eg the
Filter) class. Also create new logic functions for use by both exports and reports modules where functionality is identical.
I understand there is no right answer, but I'm looking for advice from those who have been down this road already. What do you recommend? What do you regret?
Also the Single Responsibility Principle sounds like it would be applicable here. Would it dictate completely separate modules though? Or would it allow for sharing components of a model and/or just the logic?