Question

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 ?

Was it helpful?

Solution

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();
    }
}

OTHER TIPS

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.

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?

The fact that the supply is continuous means that it will have to be checked after a specified time interval. If this is not what you are looking for, you may have to clarify your question.

The most logical approach to this problem (assuming you dont have event-based or signal/slot programming) would to have the car check the state of the engine, every time interval of your choice, and if the engine needs more oil, the car should read some data from the tank and pass it to the engine.

Here is a simple pseudocode example to demonstrate what I mean:

class Engine
{
    void start()
    {
        while(true)
        {
            // do engine stuff here
        }
    }

    void getOil(int amount)
    {
        // do stuff with oil
    }
}

class Tank
{
    int oilAmount
    boolean hasOil

    int giveOil()
    {
        return oilAmount
    }
}

class Car
{
    Tank tank
    Engine engine

    void start()
    {
        engine.start()
        while(true)
        {
            engine.getOil(tank.giveOil())
            sleep(100)
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top