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
Filter
class as defined in the export model and delete theFilter
class 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 theFilter
) 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?