0

I have Vehicles different types of Fuels (petrolium, helium, electricity...) to charge them with. Apparently petrolium and electricity have different units. I am going to process different fuels in a similar manner with a FuelingStation in future. How to store the Fuel info?

Object Fuel with amount and units? Object of type FuelType and a float fuelAmount inside a Vehicle class?

I undersand, It is a broad question, but what are the general suggestions?

Sashko Lykhenko
  • 1,554
  • 4
  • 20
  • 36

1 Answers1

1

I think having different classes for multiple fuel types is not the right solution, because it's not Fuel's responsibility to calculate its consumption, but car's. I believe that instead there should be multiple types of cars, which use different fuel types and implement calculateFuelConsumption() and fillFuel() differently.

For fuel types I believe all is needed is a simple enum and modelling a Fuel class is not necessary until it would be used for storing different fuel specific properties which doesn't seem to be the case here.

Below is what I believe to be a reasonable solution which implements an enum for various fuel types, a static map for retrieving fuel unit names and a factory pattern for creating different types of cars, based on their fuel type:

class Car
{
public:
    enum FuelType
    {
        UNKNOWN_FUEL,
        PETROLEUM_FUEL,
        ELECTRICITY_FUEL,
        HELLIUM_FUEL
    };

    Car();

    FuelType getFuelType() const { return m_fuelType; }
    std::string getFuelUnit(FuelType type) { return m_fuelUnits.at(type); }
    virtual float calculateFuelConsumption(float distance, float speed) const = 0;
    virtual void fill(FuelType fuelType) = 0;

private:
    FuelType m_fuelType;
    static std::map < FuelType, std::string> m_fuelUnits;
};

std::map < Car::FuelType, std::string> Car::m_fuelUnits
{
    { Car::UNKNOWN_FUEL, "unknown" },
    { Car::PETROLEUM_FUEL, "litres" },
    { Car::ELECTRICITY_FUEL, "Ah" },
    { Car::HELLIUM_FUEL, "cubic metres" }
};

class PetrolFueledCar : public Car
{
public:
    // ...
    float calculateFuelConsumption(float distance, float speed) const { /* ... */ }
    void fill(FuelType fuelType)  { /* ... */ } 
};

class HelliumPoweredCar : public Car
{
public:
    // ...
    float calculateFuelConsumption(float distance, float speed) const { /* ... */ }
    void fill(FuelType fuelType)  { /* ... */ }
};

class CarFactory
{
public:
    static unique_ptr<Car> newCar(Car::FuelType fuelType)
    {
        if (fuelType == Car::PETROLEUM_FUEL)
            return new PetrolFueledCar;
        if (fuelType = Car::HELLIUM_FUEL)
            return new HelliumPoweredCar;
        // ...
    }
};
jaho
  • 4,852
  • 6
  • 40
  • 66