Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP design : Car - Connection between Tank and Engine

I'm not sure whether I'm violating OOP conepts insanely.

Say there is a Carclass which "has" an Engine and a Tank.

When the Engine is operating , it will take oil from the Tank (say unit by unit per a cycle though oil is uncountable)

How should the Engine get Oil from the Tank ? (When both are fields of Car?)

Actually an Engine should be continually " Supplied" oil rather than "gets" oil.
There should be "OilCirculatingSystem" which gets Oil from the Tank
and supplies to Engine.
How can I model this system in classes ?
Is there a suitable Design Pattern? enter image description here

** * Edit : Simply ,how to have an "Flow of Oil" from Tank to Engine ? (Is it Oil's responsibility to flow from the Tank to Engine when a valve is opened ?

like image 705
Dinushan Avatar asked Oct 22 '11 16:10

Dinushan


3 Answers

I'm sorry if it fries the brain. Implementation of methods is missing but you get the idea I hope.

class Tank
{
    Oil oil;

    public Tank(OilPipe pipe)
    {
        pipe.OilNeeded += new EventHandler<OilNeededEventArgs>(pipe_OilNeeded);
    }

    public void FillOil(Oil oil) { }

    void pipe_OilNeeded(object sender, OilNeededEventArgs e)
    {
        e.Oil = oil.SubtractLiters(5);
    }
}

class OilPipe
{
    public event EventHandler<OilNeededEventArgs> OilNeeded;

    public Oil SuckOil();
}

class Piston
{
    public void Move() { }
}

class Oil
{
    public Energy Burn() { }
}

class Energy
{
    public void Push(Piston piston) { }
}

class Engine
{
    OilPipe oilPipe;

    public Engine(OilPipe oilPipe, Piston piston)
    {
        this.oilPipe = oilPipe;
    }

    public void MovePiston()
    {
        Oil oil = oilPipe.SuckOil();
        Energy energy = Burn(oil);
        energy.Push(piston);
    }
}

class Car
{
    Engine engine;

    public Car(Engine engine, Tank tank)
    {

    }

    public void Accelerate()
    {            
         engine.MovePiston();
    }
}
like image 180
Muhammad Hasan Khan Avatar answered Nov 05 '22 17:11

Muhammad Hasan Khan


Car analogies are never perfect, because cars and engines are actually very complex systems. You have to ignore a lot of things to model them simply. Your problem is that you don't seem to understand how an engine works in the first place.

The oil pan is part of the engine, not the car. The gas tank is part of the car, but not the engine. You have an oil pump (also part of the engine) that pumps oil into the cylinders of the engine. Most cars (maybe all) don't "check the oil level" and refuse to start. The engine will simply seize if it doesn't get enough oil. Likewise, if it doesn't get enough gas, it doesn't check the gas tank level.. it just runs out of fuel.

It would be more like this:

class Car
{
    Engine engine;
    GasTank gasTank;

    StartEngine() { engine.Start(); }
}

class Engine
{
    Timer timer;
    OilPan oilPan;
    OilPump oilPump;
    public Engine() { oilPump = new OilPump(oilPan, this); }
    Start() { timer.Start(oilPump); }
    InjectOil() {}
}

class Timer
{
    OilPump op; // This is a reference
    public Timer(OilPump op) { _op = op; }
    Revolve() { op.Pump(); }
}
class OilPump {
    OilPan _oilPan; // Reference
    Engine _engine; // Reference

    OilPump(OilPan oilPan, Engine engine) { _oilPan = oilPan; _engine = engine; }
    Pump() { _engine.InjectOil(_oilPan.GetOil); }
}

The timer reprsents the revolution of the engine, as it revolves, it actuates the oil pump which pumps oil into the cylinders. Oil is not typically "consumed", like fuel. It is recycled. It can break down over time, and in some engines that are in bad shape, it can burn.

The Oil Pump reference represents a mechanical linkage between the engine and the oil pump (typically gears turn it). The Timer does not have an oil pump, it has a reference to an oil pump.

The gas tank would work in a similar fashion.

Again, this is all imperfect (very imperfect), because there is so much missing.

like image 37
Erik Funkenbusch Avatar answered Nov 05 '22 17:11

Erik Funkenbusch


I would say that the Car itself is the OilCirculatingSystem.

class Car
{
   Tank tank;
   Engine engine;
   start()
   {
   //whatever
   }
   feedEngine()
   {
      while ( tank.hasOil() )
      {
          tank.getOil();
          engine.giveOil();
      }
   }
}

The Car itself is already the the class connecting all your components together, why would you need another one?

like image 20
Luchian Grigore Avatar answered Nov 05 '22 16:11

Luchian Grigore