2011-10-22 18 views
7

No estoy seguro de si estoy violar conepts POO locamente.

Digamos que hay una clase Car que "tiene" un Engine y un Tank.

Cuando el Engine está en funcionamiento, se necesitará aceite de la Tank (decir unidad por unidad por un ciclo bien el petróleo es incontable)

¿Cómo se debe obtener la Engine El aceite de la Tank? (Cuando ambos son campos de Car?)

En realidad, un Engine debe ser aceite "Suministrado" continuamente más bien que "obtiene" aceite.
Debe haber "OilCirculatingSystem" que obtiene del aceite de la Tank
y suministros a Engine.
¿Cómo puedo modelar este sistema en clases?
¿Hay un patrón de diseño adecuado? enter image description here

** * Editar: Simplemente, la forma de tener un "flujo de petróleo" de Tank a Engine? (¿Es Oil 's responsabilidad fluya desde el Tank a Engine cuando se abre una válvula?diseño de programación orientada a objetos: coches - Conexión entre el tanque y el motor

+0

Mi comprensión de los motores de los automóviles puede ser defectuosa, pero ¿no es el tanque de aceite una parte de todo el conjunto del motor? –

+0

No relacionado con su pregunta, pero importante, pienso: 'checkEngineOil' realmente no transmite para qué lo está utilizando. Realmente estás diciendo, 'si tengo suficiente aceite para comenzar'. Sugeriría algo en la línea de 'if (tank.oilLevel()> OIL_NEEDED_TO_START_ENGINE)'. –

Respuesta

4

Lo siento si fríe el cerebro. La implementación de métodos falta, pero se obtiene la idea, espero.

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

Ok. Tengo la idea, excepto "¿Cuándo ocurre el evento pipe_OilNeeded? ". Debería ser cuando SuckOil() ¿verdad? .Eventos son difíciles de entender. Leeré [esta respuesta sobre los eventos] (http://stackoverflow.com/questions/213638/how-do-c-sharp-events-work-behind-the-scenes/213651# 213651) varias veces más y tratar de entender. – Dinushan

+0

@ D-Shan Sí cuando se invoca SuckOil, la clase dispara el evento pidiendo a la fuente que proporcione aceite. –

1

El hecho de que la oferta es medio continuo que va a tener que ser comprobadas después de un intervalo de tiempo especificado. Si no lo es usted está buscando, puede que tenga que aclarar su pregunta

El enfoque más lógico para este problema (suponiendo que no tenga programación basada en eventos o señal/ranura) sería hacer que el automóvil verifique el estado del motor, cada intervalo de tiempo de su elección, y si el motor necesita más petróleo, el coche debe leer algunos datos del tanque y pasarlo al motor.

Aquí se muestra un ejemplo de pseudocódigo sencilla para demostrar lo que quiero decir:

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) 
     } 
    } 
} 
2

, diría que el Car sí mismo es el OilCirculatingSystem.

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

El Car sí ya es el la clase de conectar todos los componentes juntos, ¿por qué se necesita otro?

+0

Ok. Tiene sentido. Podemos tener después de que el automóvil "inicia" una conexión entre el motor y el tanque, el motor tiene acceso al tanque y obtiene directamente el aceite del tanque y el automóvil no necesita hacerlo para el motor. – Dinushan

+0

@ D-Shan como yo lo veo, eso violaría los principios del acoplamiento flojo (mira eso). No hay razón para que el tanque y el motor tengan una conexión. Deben contener sus propias lógicas y nada más. Un motor puede ser alimentado por gas directamente desde la bomba, no necesariamente desde el tanque. El tanque no necesariamente tiene que alimentar un motor. Entonces, ¿por qué conectarlos? El buen OOP significa que las clases están ligeramente acopladas y contienen su propia lógica. Esta lógica pertenece al automóvil, ya que básicamente eso es lo que es un automóvil: un medio para que los diferentes componentes interactúen entre sí. –

+0

Lo que me confunde es el comportamiento del aceite. En realidad, el aceite "fluye" del tanque al motor en lugar de que alguien "transporte" el aceite del tanque al motor – Dinushan

3

Las analogías de los automóviles nunca son perfectas, porque los automóviles y los motores son en realidad sistemas muy complejos. Tienes que ignorar muchas cosas para modelarlas simplemente. Tu problema es que, al parecer, no entiendes cómo funciona un motor.

El cárter de aceite es parte del motor, no el coche. El tanque de gasolina es parte del automóvil, pero no del motor. Usted tiene una bomba de aceite (también parte del motor) que bombea aceite en los cilindros del motor. La mayoría de los autos (quizás todos) no "controlan el nivel de aceite" y se niegan a comenzar. El motor simplemente se aprovechará si no obtiene suficiente aceite. Del mismo modo, si no obtiene suficiente gas, no verifica el nivel del tanque de gasolina ... simplemente se queda sin combustible.

Sería más a esto:

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

El temporizador reprsents la revolución del motor, mientras que gira, se acciona la bomba de aceite que bombea aceite en los cilindros. El petróleo no suele "consumirse", como el combustible. Es reciclado Se puede romper con el tiempo, y en algunos motores que están en mal estado, puede arder.

La referencia de la bomba de aceite representa un enlace mecánico entre el motor y la bomba de aceite (normalmente los engranajes lo giran). El temporizador no tiene una bomba de aceite, tiene una referencia a una bomba de aceite.

El tanque de gasolina funcionaría de manera similar.

De nuevo, todo esto es imperfecto (muy imperfecto), porque falta mucho.

Cuestiones relacionadas