Ver Mensaje Individual
  #8 (permalink)  
Antiguo 06/08/2014, 01:44
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años
Puntos: 320
Respuesta: Esta forma de programar es correcta

Depende de lo quieras hacer, esto:
Código PHP:
Ver original
  1. class A
  2. {
  3.     function i()
  4.     {
  5.         return "Hola";
  6.     }
  7. }
  8. class B
  9. {
  10.     function v()
  11.     {
  12.         $f=new A();
  13.         return $f->i();
  14.     }
  15. }
  16.  
  17. $dd=new B();
  18. echo $dd->v();
Si lo haces porque lo que quieres es que un metodo de B se comporte como uno de A, esta mal.
Hay (a menos) tres alternativas:
1)
Código PHP:
Ver original
  1. class A
  2. {
  3.     function i()
  4.     {
  5.         return "Hola";
  6.     }
  7. }
  8.  
  9. $f=new A();
  10. echo $f->i();

2)
Código PHP:
Ver original
  1. class A
  2. {
  3.     function i()
  4.     {
  5.         return "Hola";
  6.     }
  7. }
  8. class B
  9. {
  10.     function v($f)
  11.     {
  12.         return $f->i();
  13.     }
  14. }
  15.  
  16. $dd=new B();
  17. $f=new A();
  18. echo $dd->v($f);

3)
Código PHP:
Ver original
  1. class A
  2. {
  3.     function i()
  4.     {
  5.         return "Hola";
  6.     }
  7. }
  8. class B extends A
  9. {
  10.     function v() // Metodo alias
  11.     {
  12.        return $this->i();
  13.     }
  14. }
  15.  
  16. $dd=new B();
  17. echo $dd->v();

Sin embargo, la tercer opcion es la mas peligrosa de todas, en el sentido de que solo debes extender una clase, si hay una relacion de Generalizacion entre ambas, por ejemplo, imaginate un Tablero y una Casilla, el tablero conoce a la casilla y la casilla conoce al tablero, pero la casilla no es una extencion del tablero, por lo tanto no lo hereda.

Código PHP:
Ver original
  1. class Tablero
  2. {
  3.     private $casillas = [];
  4.  
  5.     function setCasillaRoja($nro)
  6.     {
  7.         if(!isset($this->casillas[$nro]))
  8.             $this->casillas[$nro] = new Casilla();
  9.  
  10.         return $this->casillas[$nro]->setColor("Rojo");
  11.     }
  12. }
  13. class Casilla
  14. {
  15.     private $color;
  16.  
  17.     function setColor($color)
  18.     {
  19.          if($this->color == $color)
  20.             return "El color no cambio";
  21.          
  22.          $this->color = $color;
  23.          return "El color se cambio";
  24.     }
  25. }
  26.  
  27. $board=new Tablero();
  28. echo $board->setCasillaRoja(1);
  29. echo $board->setCasillaRoja(2);
  30. echo $board->setCasillaRoja(1);

Del codigo anterior la unica linea en discucion es:
Código PHP:
Ver original
  1. $this->casillas[$nro] = new Casilla();

Entonces hay que pensar en el contexto, la pregunta de oro es: ¿Para cuantas cosas quiero que me sirvan esta clases?

Las posibles respuestas son:

1) Solo para este juego en particular.
2) Para todos los juegos que se me ocurran con este tipo de tablero.
3) Para todos los juegos de tablero del mundo.

Si la respuesta es la 1 o la 2, entonces el codigo esta bien y no hay que cambiar nada.

Si la respuesta es la tercera, entonces estamos en un problema, porque no todos los juegos de tablero tienen las mismas casillas, hay que hacer uso del patron Factory o/y usar interfaces.

Los problemas no surgen cuando queres hacer andar algo, sino cuando queres que ese algo te sirva para todo, entonces tenes que hacer abstracciones, muchas y variadas (Eso son los patrones de diseño ni mas ni menos, tecnicas de abstraccion para diferentes problematicas).

Se dice comunmente que usar patrones y buscar siempre algoritmos que sirvan para todo (genericos) es mejor, sin embargo, esto muchas veces no es verdad, te doy un simple ejemplo: PDO.

Si usas PDO puedes usar cualquier motor de base de datos, pero las consultas demoran mas que con un controlador nativo, pretende que cambiando una linea de configuracion puedas pasar de una base de datos FireBird a SQlite sin nada mas, y sin embargo, tienes que reescribir todas las sentencias (o gran parte de ellas, volviendo al ejemplo, el tablero del Monopoly no es el mismo tablero que el del Ajedrez, sus casillas no son las mismas, ni siquiera se comportan igual, entonces ¿Tiene sentido implementar patrones, usar interfaces, traits y demas artilugios solo para tener una clase Tablero bien abstracta que sepa jugar al ajedrez y al monopoly?

Personalmente no le veo el sentido, prefiero que las clases se acoplen y funcionen rapido.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios