0

We have 2 vehicle types in our system Car and Bike. Both can be associated with a Report.

There are components in our system which operate on Report but when dealing with the report they need to check if the report is for a Bike or for a Car.

I'm trying to decide between these 2 options

  • Create a report type for each i.e. a BikeReport and a CarReport. This allows me to do above check without fetching the associated vehicle but it makes the data model more complex.
  • Create only 1 report type Report and fetch the associated vehicle when I need to know the vehicle type. This keeps the data model simple but requires more requests to the DB.

I suppose it will depend on whether I'm more comfortable with the additional DB requests or the more complicated data model but wanted to see what other people think.

Thanks

2
  • Why does the Report need to know the type of Vehicle? Sounds like maybe the Vehicle could have a method to GenerateReport if that knowledge is truly needed.
    – mmathis
    Commented Jan 19, 2023 at 2:19
  • Report would have a Vehicle ID. There would be a service called ReportProcessor which takes reports and processes them. ReportProcessor needs know what type of vehicle the report is for. If we keep Report generic then ReportProcessor has to fetch the Vehicle to check what type it is.
    – tim
    Commented Jan 19, 2023 at 2:23

2 Answers 2

3

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.

1
  • Thanks for the input. I don't expect the reports to deviate from each other at all and we already have a caching layer so the additional query argument doesn't hold and we can pick the simpler data model. Thanks.
    – tim
    Commented Jan 19, 2023 at 16:00
0

The question as stated is a bit vague.

trying to decide between these 2 options:

  1. Create a report type for each ...
  2. Create only 1 report type Report

Based on what you have disclosed so far, definitely go with option 2.

There are clearly commonalities among vehicles: num_people_carried, time departed, time returned, kilometers traveled.

There may be energy expenditure details to report on, such as liters of petrol or KWh used, which splits along some e-bike / plugin car axis. Delegate that to per-class methods, and consume generic aspects through inheritance.

Not the answer you're looking for? Browse other questions tagged or ask your own question.