I think you have the wrong decision criteria in focus.
You are trying to make this decision based on a few additional queries which may be required to determine the vehicle type. This is first and foremost a performance argument. But performance should only become of interest when you have a real, measurable bottleneck, which you currently have not, otherwise you would not have asked here.
Here are the points you should really put into focus:
How much code duplication would separating those two reports BikeReport
and CarReport
cause? Code duplication is a sign you should try a find a generic solution.
Will not separating those two reports make you code become full of conditionals of the form if vehicle is Car ... else ...
? That's a point against a generic solution.
Can you create two reports BikeReport
and CarReport
, but then refactor the duplicated code into a common place? For example, a common base class Report
? So you get "the best of both worlds"?
In case of a generic solution: can you replace the mentioned conditionals by polymorphism (using the strategy pattern, for example)?
Is there a chance you will need to support more vehicle types with different report variants in the near future? If yes, do you need to let a second team make the extensions, which should be able to do this without touching your code? If that's not the case, your design can be kept significantly simpler than in the opposite case.
Consider also to start with a simple design first, and refactor as you go. None of your decisions is written in stone. Focus on avoiding duplicate code, and on avoiding complex conditionals.
And when you really notice performance issues in the future: those can be solved within the bounds of each design. Regardless of the solution you pick, some component will have to determine the vehicle type at some point in time. If you don't want to query the DB multiple times, cache the information somewhere once you got it (for example as a type flag in your generic Report
, maybe implicitly as the type of a strategy object), and reuse that information later.
Report
need to know the type ofVehicle
? Sounds like maybe theVehicle
could have a method toGenerateReport
if that knowledge is truly needed.Report
would have aVehicle
ID. There would be a service calledReportProcessor
which takes reports and processes them.ReportProcessor
needs know what type of vehicle the report is for. If we keepReport
generic thenReportProcessor
has to fetch theVehicle
to check what type it is.