PHP orientado a objetos 3: colaboración entre clases

En esta entrada veremos cómo pueden colaborar entre sí las distintas clases.

hiroshige

archivado en: PHP/AJAX / 5 marzo, 2013 / taller:

Ya sabemos qué es la encapsulación y la ocultación en la programación orientada a objetos y cómo se maneja en PHP. En esta entrada vamos a ver otro concepto fundamental, que es la colaboración entre clases.

En general, conviene que cada clase tenga un cometido específico y no para varias cosas. Por ejemplo, si una clase sirve para detectar si la conexión a una web proviene de un móvil, lo que debe hacer es solo eso y ya con otra pintamos la página de una manera u otra en función del resultado de la primera.

Además, es mejor cuanta más genérica sea su función. Es decir, es mejor una clase que dibuje una tabla en función de unos parámetros, que otra que pinta un tipo de tabla en concreto para una determinada web.

Por ejemplo, esta sería una clase muy chapucera:

class Sumar

{

protected $numeroA = 3;

protected $numeroB = 4;

public function suma() {

return $this->numeroA + $this->numeroB;

}

}

Esta clase solo sirve si necesitamos el número 7. Es incapaz de hacer nada más, por lo que solo podríamos usarla en casos muy concretos. En cambio esta otra...

class Sumar

{

private $numeroA;

private $numeroB;

public function __construct ($inicializaNumeroA, $inicializaNumeroB) {

$this->numeroA  = $inicializaNumeroA;

$this->numeroB = $inicializaNumeroB;

}

public function devuelveSuma() {

return $this->numeroA +$this->numeroB;

}

}

...es mucho más útil, ya que permite sumar dos números cualesquiera:

$miSuma = new Sumar (3, 4);

echo  $miSuma->devuelveSuma();

Entao, para que las clases sean lo más genéricas posible y, además, cada una se ocupe de lo suyo, es importante que se puedan relacionar entre sí, lo cual se puede hacer de dos maneras: mediante la colaboración, que es lo que vamos a ver en esta entrada, y mediante la herencia, como veremos en la siguiente de esta serie.

Combate fatal

En la línea de desarrollo de clases utilísimas para la vida real, vamos a preparar una aplicación que calcule las posibilidades de supervivencia de un estegosaurio contra un velocirraptor.

En un primer momento, podríamos pensar que necesitamos tres clases, una para el estegosaurio, otra para el velocirraptor y una tercera para calcular el resultado del encuentro, pero eso sería incurrir en el modo chapucero que explicaba antes, ya que los dos bichos pueden encuadrarse en la misma clase dinosaurios, pues solo varían sus parámetros particulares, no sus generalidades (los dos comen, tienen color, tienen fuerza...).

Así, de momento solo necesitamos una clase que defina cada objeto dinosaurio:

class Dinosaurios

{

private $fuerza;

public function __construct($inicializaFuerza) {

$this->fuerza = $inicializaFuerza;

}

public function devuelveFuerza () {

return $this->fuerza;

}

}

Ahora solo tenemos que crear los dos objetos-dinosaurio, cada uno con su propia fuerza, pero no vamos a hacerlo en cualquier lado, sino en otra clase que colaborará con la primera. Es decir, desde la clase CalculaEncuentro vamos a llamar a la segunda para inicializar los objetos-Dinosaurio.

class CalculaEncuentro

{

public function calculador() {

$mi_estegosaurio = new Dinosaurios (30);

$fuerzaEstegosaurio = $mi_estegosaurio->devuelveFuerza();

$mi_velocirraptor = new Dinosaurios (10);

$fuerzaVelocirraptor = $mi_velocirraptor->devuelveFuerza();

if ($fuerzaEstegosaurio > $fuerzaVelocirraptor ) {

return "ha ganado el estegosaurio";

} else {

return "ha ganado el velocirraptor";

}

}

}

Y ya sí en el código normal de la página creamos un objeto CalculaEncuentro:

$mi_calculaencuentro = new CalculaEncuentro ();

echo $mi_calculaencuentro->calculador();

En realidad, este ejemplo no sería correcto, ya que lo suyo es que la clase CalculaEncuentro fuera más general, pero me sirve para mostrar cómo se crea un objeto dentro de una clase para «colaborar» con otra clase. Esto quedará más claro con el siguiente ejemplo, una calculadora de distancias siderales

Calculadora sideral

Para terminar de asentar lo expuesto en este post y recordar los métodos getter y setter del anterior, vamos a realizar una práctica. La NASA nos ha encargado una aplicación que calcule cuánto se tarda en llegar a algunos planetas con algunos vehículos.

Estos son los datos.

Planetas destino:

  • Venus 108.200.000 km
  • Saturno 1.429.400.000 km
  • Urano 2.870.990.000 km
  • Neptuno 4.504.300.000 km
  • Plutón 5.913.520.000 km

Velocidad vehículos / hora:

  • Monopatín: 2km.
  • Bicicleta: 20km.
  • Dirigible: 16km.
  • Submarino: 98km.

Solución

1). Formulario

En la página principal de la aplicación tenemos un formulario en el que el usuario escoge a qué planeta ir y en qué vehículo. Me ahorro el código que es más simple que un botijo.

2) En la página que recogemos los datos del formulario, obtenemos dos variables, una con el nombre del planeta y otra con el vehículo. Pongamos por ejemplo que el astronauta quiere ir a Venus en dirigible.

  • $planeta = "Venus";
  • $vehiculo = "Dirigible";

3) Ya veremos que cada clase debe ir en su propio fichero, pero para no liarnos ahora, en la misma página que recogemos las variables vamos a incluir tres clases:

a) Una guarda la información con la distancia a la que se encuentra cada planeta. Podemos leer esa información, pero nada más.

class planetas

{

private $arrayPlanetas = array ('Venus'=>108200000,

'Saturno'=>108200000,

'Urano'=>108200000,

'Neptuno'=>108200000,

'Pluton'=>108200000);

public function getterPlaneta ($recogePlaneta) {

$distanciaPlaneta = $this->arrayPlanetas[$recogePlaneta];

return $distanciaPlaneta;

}

}

b) Otra es muy similar, pero con la velocidad de los vehículos

class vehiculos

{

private $arrayVehiculos = array ('Monopatin'=>2,

'Bicicleta'=>20,

'Dirigible'=>16,

'Submarino'=>98);

public function getterVehiculo ($recogeVehiculo) {

$velocidadVehiculo = $this->arrayVehiculos[$recogeVehiculo];

return $velocidadVehiculo;

}

}

c) Y la tercera es la que se encarga de realizar la operación:

class calculavelocidad {

public function devuelveResultado ($recogePlaneta, $recogeVehiculo) {

$mi_planeta = new planetas();

$distancia = $mi_planeta->getterPlaneta($recogePlaneta);

$mi_vehiculo = new vehiculos();

$velocidad = $mi_vehiculo->getterVehiculo($recogeVehiculo);

return ($distancia/$velocidad)/24;

}

}

4) Y ya solo nos faltaría crear un objeto $calculavelocidad...

$mi_calculaVelocidad = new calculavelocidad ();

echo "Hasta ".$planeta. " en ".$vehiculo." vas a tardar: ";

echo $mi_calculaVelocidad->devuelveResultado($planeta, $vehiculo);

echo " días";

En síntesis:

  • Cada clase debería servir para una sola cosa.
  • Es mejor que las clases sean lo más genéricas posibles y sus posibilidades no se reduzcan a solucionar algo en concreto.
  • Para que las clases colaboren entre sí se pueden crear objetos dentro de una clase.

En la próxima entrada veremos qué es la herencia y ya en la siguiente cómo colocar cada clase en su propio archivo sin volvernos tarumbas con trescientos mil requires...

|| Tags: ,

valoración de los lectores sobre PHP orientado a objetos 3: colaboración entre clases

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4.3 sobre 5 (28 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.