C# – Refactoring a Problem

Some days ago I have decided to take a look at one of the homeworks problem of the OOP course at SoftUni. Then, I have decided to solve it with my VBA OOP knowledge, implementing it in C#. Whether VBA is an OOP language, is an opened discussion with multiple opinions.

This is how the problem looked like:

Problem Definition

Write a program that models 2 vehicles (a Car and a Truck) and simulates driving and refueling them. Car and truck both have fuel quantity, fuel consumption in liters per km and can be driven a given distance and refueled with a given amount of fuel. It’s summer, so both vehicles use air conditioners and their fuel consumption per km is increased by 0.9 liters for the car and with 1.6 liters for the truck. Also, the truck has a tiny hole in its tank and when its refueled it keeps only 95% of the given fuel. The car has no problems and adds all the given fuel to its tank. If a vehicle cannot travel the given distance, its fuel does not change.

Input

  • On the first line information about the car inthe format: “Car {fuel quantity} {liters per km}”
  • On the second line – info about the truck inthe format: “Truck {fuel quantity} {liters per km}”
  • Onthe third line the number of commands N that will be given on the next N lines
  • On the next N lines – commands in the format:
  • “Drive Car {distance}”
  • “Drive Truck {distance}”
  • “Refuel Car {liters}”
  • “Refuel Truck {liters}”

Output

  • After each Drivecommand, if there was enough fuel, print on the console a message in the format:
  • “Car/Truck travelled {distance} km”
  • Iftherewas not enough fuel,print: “Car/Truck needs refueling”
  • After the End command, print the remaining fuel for both the car and the truck, rounded to 2 digits after the floating point in the format:
  • “Car: {liters}”
  • “Truck: {liters}”

Examples

Input Output
Car 15 0.3
Truck 100 0.9 4
Drive Car 9
Drive Car 30
Refuel Car 50
Drive Truck 10
Car travelled 9 km
Car needs refueling
Truck travelled 10 km
Car: 54.20
Truck: 75.00
Car 30.4 0.4
Truck 99.34 0.9 5
Drive Car 500
Drive Car 13.5
Refuel Truck 10.3
Drive Truck 56.2 Refuel Car 100.2
Car needs refueling
Car travelled 13.5 km
Truck needs refueling
Car: 113.05
Truck: 109.13

My implementation

was to make a parent class Auto and to inherit from it the classes Car and Truck. In these, I had separate functions for checking the fuel, driving and the overriding of the ToString(). The Main function is pretty neat:

Still, there are other functions, which were not that good – DriveInfo() and WriteFuelRequest() were taking the typeOfAuto as a string, which seemed somehow bad, as there should be another way:

There were some other tiny smells, which I was not happy with, but as far as it passed the test, I was more eager to take a look at the original solution. The whole code is here.

Original Solution

So, I was curious to see the original solution and to see what could be learned from it. First thing that I liked there was putting the Car, Truck and Vehicle classes in a Model folder. This was a good practice, following the structure of the EF.

Then the overriding of the Refuel() method for the truck was done pretty neatly – it actually used the original method and added a line for the wasted fuel:

The constructor of the Car() and the Truck() uses the base constructor, adding the air conditioning consumption. Thus, no additional logic is needed for the air conditioning later. In my solution I put it in the driving logic:

but in general, probably the correct building of the constructor was a bit better:

The last thing I liked from the original solution was the reflection for the ToString() overriding:

Indeed, it is useful this way, although one be careful with using it – the parent class should not know a lot about its children.

In general, this is it. The idea of this article is to show, that after solving a problem yourself, there is always something to learn from any other solution of the same problem. A way to go.

Cheers! 🙂

Tagged with: , ,