SlideShare una empresa de Scribd logo
Julio 2009 / Versión 1.8.9




 PROGRAMACIÓN ORIENTADA A OBJETOS
                      PARA


              PHP5
 "Aprende de forma simple y definitiva POO para PHP5,
  deja de ser Programador de Páginas Dinámicas y
empieza a convertirte en Desarrollador de Sistemas"




                              por Enrique Place




                       Usuario: Juan Zapata
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
2 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com




           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
3 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com




                     Licencia: http://creativecommons.org/licenses/by-nc/3.0/

           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
4 de 294        Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




                      “Este LIBro es un Servicio”

           Este Libro está licenciado bajo Creative        Commons y puedes distribuirlo con libertad a quienes
           consideres que pueda serle útil tenerlo.

           Si        adquirir el SERVICIO COMPLETO podrás tener
                 decides                                                                                 acceso    a
           usuarios.sURFORCE.com y por el período de tiempo que elijas obtendrás:

                1. Poder hacer CONSULTAS DIRECTAS AL AUTOR: cualquier parte del libro, tanto
                   dudas sobre ejemplos, capítulos, ejercicios y estas se responderán normalmente durante las
                   próximas 24-48hs (aunque lo más probable que obtengas una respuesta en pocas horas).

                2. Acceso a TODOS LOS          FUENTES: de todos los ejercicios del libro, revisados y comentados
                   por el mismo autor.

                3.   ACTUALIZACIONES             mensuales: tanto correcciones como ejemplos o hasta capítulos
                     nuevos, lo que podrá incluir a futuro acceso a material multimedia (screencasts, podcasts, etc).

                4.   Cambia el contenido del libro:                     si consideras que algún capítulo, ejemplo o
                     ejercicio podría mejorarse, o algún tema que ves no se encuentra tratado en el libro, tu
                     sugerencia será recibida y tenida en cuenta para la próxima actualización mensual del libro.

           Aprovecha la oportunidad de expandir las posibilidades de un libro digital obteniendo todo el soporte
           que no te podría dar nunca un libro tradicional (y de paso salvamos algunos bosques).

           ADQUIERE EL LIBRO COMPLETO en SURFORCE y accede a todos los servicios en



                                    http:/usuarios.surforce.com



           [ATENCIÓN: si este material se encuentra impreso, es probable que ya
                                  esté desactualizado]



           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
5 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



           Versiones del documento

           Versión    Fecha          Descripción                                      Autor

           1          1/01/2009      Primera versión                                  enriqueplace

           1.1        15/01/2009     Segunda revisión, recopilación de ejemplos       enriqueplace

           1.2        31/01/2009     15 días de revisión de contenidos                enriqueplace

           1.3        01/02/2009     Se separa como un capítulo el tema               enriqueplace
                                     “Paquetes UML” y se agrega un capítulo
                                     nuevo sobre “Excepciones”

           1.4        3/02/2009      Agrega capítulo “Debemos                         enriqueplace
                                     Profesionalizarnos” (post del blog)

           1.5        4/02/2009      Error: corrección capítulo 8, diseño 2, cambia   andresfguzman
                                     echo por retorno en clase Persona                (corrector)

           1.6        6/2/2009       Agrega nota de autor recalcando el tema de       enriqueplace
                                     los estándares de codificación definidos por
                                     Zend y que todos los ejemplos de este libro lo
                                     seguirán

           1.7        6/2/2009       Enumera los Principios que deberíamos seguir     enriqueplace
                                     los desarrolladores

           1.7.1      10/2/2009      Correcciones en fuentes, espacios, estética      Dennis Tobar (lector)

           1.7.2      28/2/2009      Cap.11: Agrega explicación sobre auto- Colabora:
                                     relación con Persona (cuadro de color verde)
                                                                                  Antonio L. Gil (lector)

           1.7.3      10/3/2009      Cap. 10: Agrega ejemplo y explicación extra      Colabora:
                                     en el caso de "qué hacer con las relaciones
                                     cíclicas / bidireccionales"                      Eduardo de la Torre
                                                                                      (lector)

           1.7.4      22/3/2009      Cap. 14: corrección en la redacción del          Colabora:
                                     resumen final
                                                                                      Raquel Diaz (lector)

           1.7.5      24/3/2009      Cap.11: Agrega explicación de "Confusión         enriqueplace
                                     común" con respecto a confundir
                                     bidireccional con cíclica (cuadro "verde")



           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
6 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



           1.7.6      26/3/2009      Cap.7: el ejemplo de calcular la edad no está    Colabora:
                                     completo, debería retornar un integer y no el
                                     valor del atributo "_fechaNacimiento"            Carlos Arias (lector)

           1.7.7      26/3/2009      Cap.10: amplía la explicación sobre              Colabora:
                                     “Multiplicidad”
                                                                                      Christian Tipantuña
                                                                                      (alumno)

           1.7.8      1/4/2009       Cap. 7: ejemplo “decirEdad” tiene un             Colabora:
                                     parámetro de más
                                                                                      Carlos Arias

                                                                                      (alumno/lector)

           1.8.0      3/4/2009       Agrega Anexo: "Qué es lo nuevo en PHP5?",        enriqueplace
                                     basado en el artículo "What's New in PHP5?"

           1.8.1      25/4/2009      Cap.19, parte 2, error, cambia "Copy" por        Colabora:
                                     "MaquinaDeEscribir"
                                                                                      Karina Diaz

                                                                                      (alumna/lector)

           1.8.2      25/4/2009      Cap.19, ajusta diagrama UML, cambia              Colabora:
                                     parámetro leer:String por texto:String en
                                     MaquinaDeEscribir                                Karina Diaz

                                                                                      (alumna/lector)

           1.8.3      15/5/2009      Revisión Cap.1                                   enriqueplace

           1.8.4      20/5/2009      Revisión Cap.2                                   enriqueplace

           1.8.5      4/7/2009       Revisión Cap.3, definición de “contexto”         enriqueplace

           1.8.6      4/7/2009       Capítulo 3 está repetido, dos capítulos tienen   enriqueplace
                                     el mismo nombre, se unifican en el capítulo 4,
                                     cambiando al nombre de “POO según los
                                     Manuales” (incluyendo ahora Wikipedia y el
                                     manual Oficial)

           1.8.7      4/7/2009       Cap.4 agrega enlaces a Wikipedia                 enriqueplace

           1.8.8      5/7/2009       Cap.5 – revisión y ampliación sobre el           enriqueplace
                                     concepto de “diseño”




           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
7 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



           1.8.9      5/7/2009       Cap.6 – revisión                         enriqueplace




                   ¡Mis más sinceros agradecimientos a lectores y colegas con sus aportes!




           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
8 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




           Sobre el Autor
                                                                        Enrique Place (35 años), nacido en
                                                                        Uruguay y actualmente viviendo en
                                                                        Argentina (pero “ciudadano de Internet”),
                                                                        es uno de los tantos “emprendedores por
                                                                        naturaleza” que cambió a los 14 años su
                                                                        fanatismo por las artes marciales
                                                                        (algunos llegaron a pensar que sería el
                                                                        sucesor sudamericano del Pequeño
                                                                        Dragón) por el fanatismo hacia la
                                                                        informática.

                                                                        Por cuestiones que solo el destino sabrá,
                                                                       tuvo la oportunidad de trabajar con los
           antiguos y míticos dinosaurios de la informática llamados Mainframes y participó en una misión para
           salvar a la raza humana de su extinción migrando aplicaciones para sobrevivir al colapso del Y2K,
           convirtiendo a diestra y siniestra código Mantis / Mainframe a Microfocus Cobol y Windows NT / Unix
           AIX.

           Paralelamente, fundó una pequeña empresa llamada LINUXTECH, quién fue la primer importadora para
           Uruguay de SuSE GNU/Linux (Alemania) y que dio los primeros pasos al evangelizar usuarios y empresas
           brindando servicios profesionales.

           De profesión “Analista Programador”, estudiante y posteriormente docente en la Universidad ORT
           (Uruguay), aprovechó todo lo que pudo aprender de arquitecturas como .Net y Java, conocer de
           Patrones de Diseño (GOF), como para darse cuenta que PHP, su verdadero amor informático, tenía un
           gran potencial por su simplicidad y pragmatismo, y que además su comunidad carecía completamente
           de una visión amplia como para entender todo lo que aún faltaba recorrer (como lo habían hecho ya
           otras tecnologías).

           Finalmente, el autor no se considera “gurú” y simplemente como “en el país de los ciegos, el tuerto es
           rey”, de la mano a su facilidad para enseñar (radicada en que aún es “alumno de todo”), es que se inicia
           en el camino de tratar de transmitir nuevos conocimientos a la Comunidad PHP.

           Este libro se escribe con el objetivo de que los actuales Programadores PHP se conviertan en el corto
           plazo en Desarrolladores PHP aprobando la materia que más les cuesta:

                                            "Programación Orientada a Objetos en PHP5"

           "Este libro fue escrito para ti, Pequeño Saltamontes"



           SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
9 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com




           Agradecimientos
           A mi familia: mi amada esposa Laura, mis amadas hijas Micaela y Martina, que
           tantas veces soportaron que su padre estuviera ausente por tener la cabeza en
           otro lado. Este fue uno de los tantos proyectos que le robó tiempo a la familia,
           pero que espero que de alguna forma u otra lo disfruten ellas.

                                               A la Universidad ORT Uruguay, gracias a los
                                               buenos docentes (también se aprende de los
                                               malos) que me tocaron en mi carrera y que me
                                               ayudaron a tener los conocimientos suficientes como para poder
                                               trabajar con PHP “de otra forma”.



           Carlos Cantonnet, docente en Análisis y Diseño Orientado a Objetos y cumpliendo el rol de "Arquitecto
           de Sistemas" en multinacionales como TATA TCS, sus excelentes clases lograron abrir mi mente con sus
           explicaciones simples, directas, y con mucho humor.
           Ahí empecé a conocer de Patrones de Diseño y la
           magia de los Principios de Diseño Orientado a Objetos.

           Nicolás Fornaro, docente en Programación Java y Análisis y Diseño, por sus muy buenas clases que, a
           diferencia de Cantonnet, me permitían tener una visión menos teórica y mucho más práctica de los
           Objetos y los Patrones de Diseño.

           A muchos colegas y amigos que de alguna forma u otra siempre apoyaron o inspiraron mis locuras, pero
           principalmente cuando alguna vez me dijeron frases como “eso no se puede”, “no vale la pena el
           esfuerzo”, “no le veo sentido”, “no vas a poder con todo”.

           Me quedo con la frase “No sabían que era imposible, por eso lo lograron”



           Sin ustedes no lo hubiera logrado ¡GRACIAS A TODOS!




           SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
           Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
10 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com




            “Revisores de este libro”
            Amigos y colegas que ayudarán con la revisión en busca de errores y/o sugerencias. Como es un libro
            que se irá actualizando mensualmente todas sus mejoras se podrán apreciar a finales de febrero 2009
            (de todas formas creo que mi orgullo me impedirá hacerles caso ;-)).




                                  Andrés Guzmán, blogger colega
                                  de PHP y Zend
                                  Chile
                                  http://bolsadeideas.cl/zsamer/




                                                                       Christian Serrón, uno de mis
                                                                       mejores alumnos
                                                                       Uruguay
                                                                       http://serron.surforce.com




                               Christopher Valderrama , colega de PHP
                               y Zend, Moderador en Foros del Web /
                               Sección POO – PHP
                               México
                               http://web2development.blogspot.com/




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
11 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com




            Prólogo
            Estimados Lectores

            Tradicionalmente se dice que el alumno en artes marciales busca toda su vida el maestro perfecto
            cuando en realidad con los años y habiendo acumulado experiencia se da cuenta que siempre estuvo
            dentro suyo. Una de las principales razones de escribir este libro fue no haber encontrado un libro
            similar para poder leer y consultar.

            A su vez estoy convencido que se pueden escribir libros “pragmáticos”, “simples” y “directos”, evitando
            entrar en disertaciones complejas de “docente que no baja al nivel del alumno que no domina el tema a
            tratar”.

            El libro es el resultado de apuntes de estudios, investigaciones, experiencia personal, y materiales que
            fueron desarrollados para el primer taller de POO para PHP5 (edición 2008), por eso verás ejercicios,
            soluciones y comentarios de los errores que estadísticamente son muy probables que cometas
            durante el aprendizaje. Me tomé el trabajo de revisar todos los capítulos, generar nuevos y a su vez
            actualizar explicaciones que fueron vertidas en los foros (la discusión con los alumnos enriqueció los
            ejemplos y debían quedar registrados de forma permanente).

            Para no ser menos, acostumbrado a intentar “un paso más allá”, este libro no será comercializado solo
            como un archivo “pdf”, la idea es ofrecer un servicio completo e intentar asegurar al lector el máximo
            de valor agregado que en este momento puedo concebir.

            Traté de hacer el libro que yo compraría, espero satisfacer tus expectativas, y si no lo logro, aún estás a
            tiempo de que lo solucione, ya que el libro “está vivo” y todas las sugerencias generarán nuevas
            actualizaciones.

            Saludos!

            Enrique Place

            enriqueplace@gmail.com

            Blog Personal
            http://enriqueplace.blogspot.com

            Blog Técnico
            http://phpsenior.blogspot.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                   SURFORCE / FORMACIÓN
12 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                       www.surforce.com




            Contenido
            Introducción: ............................................................................................................................................... 21
            ”Los Desarrolladores PHP debemos Profesionalizarnos” ........................................................................... 21
               Esta reflexión se la escribo a todos los "Programadores PHP" ............................................................... 21
               Enfrentar la realidad con madurez ......................................................................................................... 21
               Mi experiencia personal.......................................................................................................................... 22
               La culpa es enteramente nuestra ........................................................................................................... 23
               Debemos pasar de los dichos a los hechos ............................................................................................. 24
            Capitulo 1 - "Nuestros Principios como Desarrolladores" .......................................................................... 25
               Principio 1: RTFM - "Lee el Maldito Manual".......................................................................................... 27
               Principio 2: DRY - "No Te Repitas" .......................................................................................................... 27
               Principio 3: KISS - "Mantenlo Simple, Estúpido!" ................................................................................... 27
               Principio 4: Estándar de Codificación PHP / Zend................................................................................... 27
            Capitulo 2 - “Introducción a los Objetos” ................................................................................................... 29
               “Vacuidad: vaciar todos los conocimientos” .......................................................................................... 31
               “La sencillez es la mejor arquitectura “ .................................................................................................. 31
               “Lo más importante es detectar los objetos” ......................................................................................... 32
               En resumen ............................................................................................................................................. 32
            Capítulo 3 - “Cómo Pensar en Objetos” ...................................................................................................... 34
               “Lo menos importante es el código” ...................................................................................................... 36
               “Un niño pequeño” ................................................................................................................................. 36
               “El medio de comunicación” ................................................................................................................... 37
            Capítulo 4 - “POO según LOS MANUALES” ................................................................................................. 38
               “La POO según Wikipedia” ...................................................................................................................... 39
               “POO según el manual Oficial de PHP” ................................................................................................... 42
            Capítulo 5 - “Empezar a plasmar los objetos en un diseNo” ...................................................................... 44
               “Cómo representar la estructura de los objetos” .................................................................................. 46
               En Resumen ............................................................................................................................................ 51
            Capítulo 6 - “Introducción a UML” .............................................................................................................. 53
               “UML, el medio y no el fin en sí mismo”................................................................................................. 55


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                     SURFORCE / FORMACIÓN
13 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                         www.surforce.com



               “UML y el público objetivo” .................................................................................................................... 55
               “UML es independiente del lenguaje” .................................................................................................... 56
               En resumen ............................................................................................................................................. 57
            Capítulo 7 - “Cómo representar una clase en UML” ................................................................................... 58
               “Conceptos Generales” ........................................................................................................................... 60
               Mi primer diagrama UML........................................................................................................................ 60
               Cómo se traduce en código .................................................................................................................... 62
                  Sección #1 – nombre de la clase ......................................................................................................... 62
                  Sección #2 – los atributos de la clase.................................................................................................. 62
                  Sección #3 – los métodos de la clase .................................................................................................. 64
               “El Constructor” ...................................................................................................................................... 64
               Probando el objeto en un contexto determinado .................................................................................. 66
               En Resumen ............................................................................................................................................ 67
            Capítulo 8 - Ejercicio "Micaela y el Perro" .................................................................................................. 68
               Requerimientos....................................................................................................................................... 70
               Solución ................................................................................................................................................... 71
               Aplicación del “Principio KISS” ................................................................................................................ 72
               Sugerencias para enfrentar los diseños .................................................................................................. 72
               Propuesta de Diseño 1 ............................................................................................................................ 73
                  Diagrama UML .................................................................................................................................... 73
                  Traducción de UML a PHP ................................................................................................................... 74
               Propuesta de Diseño 2 ............................................................................................................................ 76
                  Cambios............................................................................................................................................... 76
                  Diagrama UML .................................................................................................................................... 76
                  Traducción UML a PHP ........................................................................................................................ 77
               En Resumen ............................................................................................................................................ 79
            Capítulo 9 - Los métodos "getter / setter" o "accesores / modificadores" ................................................ 80
               Requerimiento 1 ..................................................................................................................................... 84
               Requerimiento 4 .................................................................................................................................... 85
               En Resumen ............................................................................................................................................ 88
            Capítulo 10 - “Cómo representar las Relaciones entre clases en UML” ..................................................... 89
               La Relación de Dependencia ................................................................................................................... 91

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                       SURFORCE / FORMACIÓN
14 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                           www.surforce.com



                  Representación UML........................................................................................................................... 91
                  Cómo se traduce a código ................................................................................................................... 92
               Caso 1 – instancio un objeto B dentro de un método de A .................................................................... 92
               Caso 2 – recibo por parámetro de un método de A un objeto B............................................................ 93
               La Relación de Asociación ....................................................................................................................... 94
                  Representación UML........................................................................................................................... 94
               UML del ejemplo del Auto ...................................................................................................................... 96
               Variaciones de Asociación: Relación de Agregación y Relación de Composición ................................... 97
                  Relación de Agregación ....................................................................................................................... 97
                  Relación de Composición .................................................................................................................... 97
                  Ejemplos de Agregación y de Composición ........................................................................................ 97
               ¿Qué relaciones se deberían evitar?....................................................................................................... 99
                  Ejemplo de relación cíclica .................................................................................................................. 99
               Resumiendo rápidamente algunos conceptos complementarios ........................................................ 101
                  “Navegabilidad” ................................................................................................................................ 101
                  “Definición de Roles” ........................................................................................................................ 101
               Resumen ............................................................................................................................................... 102
            Capítulo 11 - Ejercicio "Micaela, el Perro y la Escuela” ............................................................................ 103
               Requerimientos..................................................................................................................................... 105
               Solución ................................................................................................................................................. 106
               “Errores Comunes” ............................................................................................................................... 107
               Detalle importante a tener en cuenta con las relaciones ..................................................................... 111
               El método público toString() ................................................................................................................. 113
               Lo que dice el manual de toString() ..................................................................................................... 115
               Agregando las relaciones que se ven desde Index ............................................................................... 116
               Crear la clase Index a partir de la representación UML ........................................................................ 117
               Segunda propuesta de diseño .............................................................................................................. 118
                  Diagrama UML .................................................................................................................................. 119
               En Resumen .......................................................................................................................................... 120
            Capítulo 12 - Ejercicio "La Escuela y los coches escolares"....................................................................... 121
               Requerimientos..................................................................................................................................... 122
               Guía ....................................................................................................................................................... 122

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                     SURFORCE / FORMACIÓN
15 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                         www.surforce.com



               Solución ................................................................................................................................................. 123
               “Errores Habituales” ............................................................................................................................ 123
               “Comentarios Generales” ..................................................................................................................... 125
               Navegabilidad ....................................................................................................................................... 126
               Cómo deberían ser las búsquedas ........................................................................................................ 127
               Diagrama UML ...................................................................................................................................... 128
               Resumen ............................................................................................................................................... 129
            Capítulo 13 - Ejercicio “Implementar diagrama de diseNo UML” ............................................................ 130
               Requerimientos..................................................................................................................................... 131
               Solución ................................................................................................................................................. 132
               ¿Qué sucedería si se están usando mal las relaciones? ....................................................................... 133
               Comentarios adicionales ....................................................................................................................... 134
               Errores habituales ................................................................................................................................. 135
               Consejos ................................................................................................................................................ 136
               Diagrama UML ...................................................................................................................................... 137
               Ejemplo codificado ................................................................................................................................ 138
               Resumen ............................................................................................................................................... 139
            Capítulo 14 - Ejercicio “Sistema para empresa que realiza encuestas”.................................................... 140
               Requerimientos..................................................................................................................................... 141
               Solución ................................................................................................................................................. 142
                  Posibles dificultades .......................................................................................................................... 142
                  Requerimientos presentados ............................................................................................................ 142
                  Requerimientos Erróneos ................................................................................................................. 142
                  Muchos Diseños Posibles .................................................................................................................. 143
                  Paso 1 – “Crear las clases y atributos” .............................................................................................. 144
                  Paso 2 – “Relacionar las clases” ........................................................................................................ 145
               “Receta de cocina” ................................................................................................................................ 149
               “El código”............................................................................................................................................. 150
               Index creado a “prueba y error” ........................................................................................................... 155
               Resumen ............................................................................................................................................... 158
            Capítulo 15 - “Herencia, Interfaces y Polimorfismo” ................................................................................ 159
               La Herencia............................................................................................................................................ 161

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                     SURFORCE / FORMACIÓN
16 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                         www.surforce.com



               Representación UML............................................................................................................................. 162
               Cómo se traduce a código..................................................................................................................... 163
               Caso 1 –Usuario hereda de Persona ..................................................................................................... 164
               Caso 2 –Persona agrega un constructor ............................................................................................... 166
               Caso 3 –Persona agrega su toString...................................................................................................... 167
               Caso 4 – Los usuarios necesitan un id y una fecha de ingreso ............................................................. 169
               Caso 5 – Los usuarios necesitan un id único “autogenerado” .............................................................. 170
               Explicación sobre la visibilidad de los atributos y métodos .................................................................. 173
                  “Visibilidad Pública” .......................................................................................................................... 173
                  “Visibilidad Privada”.......................................................................................................................... 173
                  “Visibilidad Protegida” ...................................................................................................................... 173
               Caso 6 – Ejemplos varios ....................................................................................................................... 174
                  Clase abstracta .................................................................................................................................. 175
                  Herencia Múltiple ............................................................................................................................. 176
                  “Sobre-escritura” de métodos .......................................................................................................... 177
                  Evitar la herencia y la “sobre-escritura” de métodos ....................................................................... 178
               “Generalización” versus “Especialización” ........................................................................................... 179
               Entonces, ¿qué es Polimorfismo? ......................................................................................................... 180
                  La implementación............................................................................................................................ 181
                  “Diseño más robusto” ....................................................................................................................... 182
               ¿La herencia está limitada? .................................................................................................................. 182
               Las interfaces: “el poder desconocido” ................................................................................................ 184
                  Implementación ................................................................................................................................ 185
                  Cómo funciona .................................................................................................................................. 186
                  Detalles importantes......................................................................................................................... 186
               Repaso de lo visto hasta el momento ................................................................................................... 187
                  Las interfaces son “contratos de implementación” .......................................................................... 188
                  Anexo ................................................................................................................................................ 188
               Resumen ............................................................................................................................................... 189
            Capítulo 16 - Ejercicio “Clase de Persistencia”......................................................................................... 190
               Requerimientos..................................................................................................................................... 191
               Solución ................................................................................................................................................. 193

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                    SURFORCE / FORMACIÓN
17 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                        www.surforce.com



               Primer escenario: “crear una conexión a la base de datos” ................................................................. 194
               Segundo escenario: “crear una clase de persistencia” ......................................................................... 194
               Tercer escenario: “abstraer el tipo de base de datos” ......................................................................... 194
               Diseño UML ........................................................................................................................................... 195
               Ejemplo codificado................................................................................................................................ 196
               Principio de diseño “Abierto / Cerrado” ............................................................................................... 200
               Resumen ............................................................................................................................................... 201
            Capítulo 17 - Ejercicio “Librería y la búsqueda de Libros” ........................................................................ 202
               Requerimientos..................................................................................................................................... 203
               Solución ................................................................................................................................................. 204
               Diseño “Borrador” (con partes incompletas) ....................................................................................... 205
               Diseño “Final” cumpliendo con todos los requerimientos ................................................................... 206
               Comentarios sobre el diseño ................................................................................................................ 208
               Resumen ............................................................................................................................................... 214
            Capítulo 18 - “Los Paquetes en UML” ....................................................................................................... 215
               Cómo se representan ............................................................................................................................ 216
               ¿Qué es una Arquitectura de 3 capas? ................................................................................................. 217
               ¿Que son entonces los Namespaces? ................................................................................................... 218
                         PHP5: Diseño en 3 capas y problemas con subdirectorios ....................................................... 218
                         "Petición para soporte de Name Spaces en PHP5"................................................................... 218
               En Resumen .......................................................................................................................................... 219
            Capítulo 19 - Ejercicio “Programación ‘Orientada a la Implementación’ vs ‘Orientada a la Interface’" .. 220
               Requerimientos..................................................................................................................................... 222
               Solución ................................................................................................................................................. 224
               Parte 1: hacer una “máquina de escribir” siguiendo el ejemplo del artículo ....................................... 225
               Parte 2: Agregar interfaces al diseño propuesto en la parte 1 ............................................................. 229
               Implementación .................................................................................................................................... 231
                  ¿Y el Diagrama de Paquetes? ............................................................................................................ 234
               El “Principio de Inversión de dependencias (DIP)” ............................................................................... 235
               Resumen ............................................................................................................................................... 237
               Comentarios adicionales ....................................................................................................................... 238


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                    SURFORCE / FORMACIÓN
18 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                        www.surforce.com



            Capítulo 20 - Ejercicio “Desarrollar un sistema de ABM de usuarios”...................................................... 239
               Requerimientos..................................................................................................................................... 240
               Solución ................................................................................................................................................. 243
               Cambios que se aplicaron en la resolución........................................................................................... 244
               Diagrama tradicional de paquetes ........................................................................................................ 245
               Diagramas de clases y sus paquetes de origen ..................................................................................... 246
               Diagramas de Secuencia ....................................................................................................................... 247
               Partes esenciales del código de la solución .......................................................................................... 249
               Resumen ............................................................................................................................................... 257
            Capítulo 21 - Anexo: “Manejo de excepciones” ....................................................................................... 258
               Introducción .......................................................................................................................................... 259
               Básicamente cómo funcionan las excepciones ..................................................................................... 261
               Estructura interna de una clase Exception ........................................................................................... 262
               Importante: PHP no tiene excepciones por defecto ............................................................................. 264
                  ¿Cuan grave es no tener Excepciones predefinidas y por defecto? ................................................. 264
               Ejemplo funcional de excepciones en PHP5 ......................................................................................... 265
               Importante: el orden de las excepciones.............................................................................................. 266
               Beneficios de las Excepciones ............................................................................................................... 267
               En Resumen .......................................................................................................................................... 268
            Capítulo 22 - Cierre del libro y reflexiones finales .................................................................................... 269
            Anexo I: "Qué es lo nuevo en PHP5?" ....................................................................................................... 273
               Características del Lenguaje ................................................................................................................. 274
               1.Modificadores de acceso "public/private/protected" ....................................................................... 274
               2. El método reservado __construct() .................................................................................................. 275
               3. El método reservado __destructor()................................................................................................. 275
               4. Interfaces .......................................................................................................................................... 276
               5. El operador "instance of" .................................................................................................................. 277
               6. Operador "final" para los métodos ................................................................................................... 277
               7. Operador "final" para la clase ........................................................................................................... 278
               8. Método reservado __clone para clonado de objetos ....................................................................... 279
               9. Atributos Constantes para las clases ................................................................................................ 281
               10. Miembros estáticos o de clase (static)............................................................................................ 282

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                                                  SURFORCE / FORMACIÓN
19 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                                                                     www.surforce.com



               11. Métodos estáticos o de clase (static) .............................................................................................. 284
               12. Clases Abstractas ............................................................................................................................ 286
               13. Métodos abstractos ........................................................................................................................ 286
               14. Validación de Tipo a través de Clases ( type hints) ......................................................................... 287
               15.Soporte a invocaciones anidadas de objetos retornados ................................................................ 288
               16. Iteradores ........................................................................................................................................ 290
               17. __autoload().................................................................................................................................... 291
            Anexo II: Recopilación de FRASES ............................................................................................................. 292
                         101 citas célebres del mundo de la informática ....................................................................... 294
                         Otras 101 citas célebres del mundo de la informática ............................................................. 294




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
20 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                Si adquieres el [libro + servicios] puedes hacer todas las
                consultas que necesites de forma directa al autor.

                Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
21 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



            Introducción:
            ”Los Desarrolladores PHP debemos Profesionalizarnos”
            Basado en el post:

            Los Desarrolladores PHP debemos profesionalizarnos o quedaremos descartados por obsoletos

            Esta reflexión se la escribo a todos los "Programadores PHP"

            Al día de hoy la mayoría de los institutos o universidades de muchos países
            siguen enseñando PHP4, o mejor dicho, programación "scripting" básica.
            Se mueven en el viejo concepto de la "programación estructurada",
            trabajando constantemente sobre código que mezcla html y sintaxis PHP,
            todo como si de una ensalada estuviéramos hablando.

            Casi paralelamente, los jóvenes autodidactas siguen por el mismo camino, tal vez ayudados por la gran
            cantidad de material repetido y obsoleto que se encuentra tanto en la web como en las editoriales de
            turno, donde a pesar que un libro haya sido impreso recientemente, los autores siguen siendo los
            mismos y escribiendo -una y otra vez- sobre los mismos temas elementales.

            Enfrentar la realidad con madurez

            Solo nos damos cuenta que estamos en un grave problema cuando nos enfrentamos a la realidad:
            salimos al mercado laboral y con inocente sorpresa vemos que se habla mayoritariamente de Java o
            .Net, de UML, desarrollos en 3 capas, lógica de negocios, persistencia, polimorfismo, frameworks,
            patrones de diseño, refactoring... y tú solo tienes una vaga idea de algunos conceptos, pero nulo
            conocimiento de si es realmente posible hacerlo con PHP...




                                         Diseño UML: Representación de Paquetes y sus relaciones

            ¿No crees que algo está pasando y que tú estás quedando fuera de la "conversación"?

            Este es el gran problema de la mayoría de los "Programadores PHP": se quedan en el "lenguaje", en la
            programación lisa y llana, rechazando todo lo que sea objetos hasta que no les queda otra salida que
            aprender a usarlos mínimamente... pues todas las nuevas herramientas solo hablan "ese" idioma.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                                   SURFORCE / FORMACIÓN
22 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                                  www.surforce.com



            ¿Hasta donde piensas que podemos llegar con tan poca preparación?


            Mi experiencia personal

            De lo que trato de hablar en este blog es de "profesionalizarnos", de copiar y mejorar, de aprender y
            evolucionar. La mayoría de los temas que expongo no son nuevos, trato de basarme en autores
            reconocidos y darle más prioridad a los conceptos que al lenguaje, y por sobre todas las cosas: ser
            simple y directo (pragmático antes que dogmático, pero sin olvidarme de lo último).

            Hay muchas cosas que desconozco de PHP y otras que directamente no uso, y nunca me baso en la
            memoria, siempre voy a buscar hasta lo más elemental al manual (doy prioridad al razonamiento por
            sobre la retención mecánica de conocimientos). Siguiendo esta metodología, mañana deberías poder
            cambiar de lenguaje y seguir trabajando sin problemas, pues los conceptos base los tendrías claros y
            estos se aplican sin importar la plataforma que
            estés usando.

            Muchas veces comento que los temas sobre los
            que escribo son elementales para muchos
            desarrolladores Java de nivel medio y alto, pero
            en el ambiente PHP esto cambia (todavía no
            hemos madurado hacia el concepto de
            "arquitectura") donde "en el mundo de los ciegos
            puedo ser rey".

            Debemos cambiar la mentalidad ahora que existe
            PHP5 y que su nueva sintaxis nos permite hacer
            muchas cosas que son habituales en el mundo

            Java.                                                      "la vida es demasiado corta para Java", detrás de la remera
                                                                                        dice "Usa PHP" (verídico)
            Por lo tanto, tenemos todas las herramientas para
            "evolucionar" y no quedarnos en las excusas.

            Programador versus Desarrollador

            Desarrollar Orientado a Objetos va más allá que crear objetos aislados que solo contienen datos,
            programar usando algunos objetos es distinto a desarrollar 100% Orientado a Objetos, ser programador
            es distinto a ser un desarrollador, un sitio web no es lo mismo que un sistema web. Existen, además
            de los objetos, "Principios de Diseño (OO)", "Patrones de Diseño (OO)", el lenguaje de diseño UML,
            frameworks, etc, y todo es perfectamente aplicable usando PHP.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
23 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Es más, muchos de estos conceptos e ideas son
            independientes al lenguaje si este cumple
            mínimamente con las características de la OO, cosa
            que sucede a partir de PHP5 en adelante y que
            PHP4 casi carece por completo.

            Finalmente, es mi visión que un programador
            resuelve problemas aislados usando un lenguaje,
            pero un desarrollador diseña e implementa una
            solución global, une los componentes en un único
            sistema integrado y es lo suficientemente
            inteligente y estratega para poder reutilizar la
            experiencia y conocimientos adquiridos en favor de         Ejemplo de Patrón de Diseño: Template Method
            los próximos desarrollos.

            Los sistemas que van quedando atrás nunca serán un lastre porque podrán ser mantenidos con el
            mínimo costo posible, permitiendo que el desarrollador pueda afrontar nuevos y enriquecedores
            desafíos.

            Todos estos detalles los percibimos claramente cuando nuestros desarrollos dejan de ser un "programa
            menor" y necesitamos crecer, pero vemos que con los conocimientos que contamos hasta el momento
            todo se nos hace cuesta arriba.

            La culpa es enteramente nuestra

            No podemos quejarnos que a los programadores Java se les paga el doble que a nosotros y que a la
            mayoría de los proyectos PHP se los desvalorice, se los trate como "algo menor", "poco serio", todo
            porque es un "simple lenguaje web" limitado en sus posibilidades.

            El "Simple Lenguaje" lo hacemos todos, al ser "Simples Programadores PHP" y nuestras son las
            limitaciones fundamentales. Perfectamente podemos tratar de trabajar "más seriamente" como lo
            hacen los "desarrolladores Java", y tratando con creatividad de suplir las carencias momentáneas (como
            el muy sonado caso de la falta de "namespaces").

            PHP se está orientando a convertir en una "arquitectura", a parecerse a un J2EE pero mucho más simple
            y directo.

            El proceso hace tiempo que inició.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
24 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



            Debemos pasar de los dichos a los hechos

            De la misma forma, creo que nos hace falta tener más "sentimiento de comunidad", como sucede
            habitualmente -hasta de forma exagerada- en el mundo GNU/Linux. No es posible que nos sigamos
            quejando que los proveedores de hosting siguen usando PHP4.

            Deberíamos hacer campañas para promover la migración a las nuevas versiones de
            PHP, pero fundamentalmente, incorporar en nuestros desarrollos las características
            avanzadas del lenguaje, e invitar a usarlo como si fuera una arquitectura, actualizar a
            nuestro equipo de desarrolladores, visitar empresas, universidades, etc.




                   ¿Tú, qué vas a hacer? ¿Te vas a quedar donde estás o te vas a subir al tren?

                                 ¿Eres parte del problema o parte de la solución?

              Tenemos que especializarnos y profesionalizarnos, el mundo pide POO, arquitecturas,
                               capas, etc, y habla en "UML"... tú, ¿en qué idioma hablas?



            Post Publicado el 30 de Abril 2006


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
25 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Capitulo 1 - "Nuestros Principios como Desarrolladores"
            Peor que usar un mal estándar o un estándar incorrecto es no seguir ninguno, de la misma forma, lo
            peor que podemos hacer es no tener ningún criterio para enfrentar los desarrollos. Para aumentar
            nuestra productividad, tanto individualmente como en equipo, debemos siempre seguir estándares y fijar
            criterios de desarrollo. Nuestro objetivo debería ser contar con una “plataforma de desarrollo” que nos
            evite tener que repensar problemas típicos y cotidianos, y concentrarnos solo en los problemas nuevos.

            Empecemos por el principio, por lo más básico y elemental… nuestros principios base.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
26 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Nadie debe empezar un proyecto grande.
                        Empiezas con uno pequeño y trivial y nunca
                            debes esperar que crezca; si lo haces
                        solamente sobre-diseñarás y generalmente
                       pensarás que es más importante de lo que lo
                        es en esta etapa. O peor, puedes asustarte
                           por el tamaño de lo que tu esperas que
                       crezca. Así que empieza pequeño y piensa en
                          los detalles. No pienses acerca de la foto
                        grande y el diseño elegante. Si no resuelve
                       una necesidad inmediata, seguramente está
                         sobre-diseñado. Y no esperes que la gente
                       salte a ayudarte, no es así como estas cosas
                            funcionan. Primero debes tener algo
                         medianamente usable y otros dirán "hey,
                       esto casi funciona para mí" y se involucrarán
                                        en el proyecto."
                                                   - Linus Torvalds




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
27 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            Principio 1: RTFM - "Lee el Maldito Manual"
                    RTFM es una sigla que significa “lee el maldito manual”, algo muy usado en los foros como
                    respuesta hacia los novatos que lo último que hacen es leerlos (lamentablemente *todo* se
                    encuentra ahí)

                    http://es.wikipedia.org/wiki/RTFM

            Principio 2: DRY - "No Te Repitas"
                    “No te repitas” significa algo muy simple: si cuando desarrollas ves que al programar “copias” un
                    código para “pegarlo en otro lado”, es muy probable que estés haciendo algo mal, ya que ese
                    código debería estar aislado y ser usado a través de parámetros.

                     Generalmente no existe razón para tener que duplicar el código, si estamos muy apurados,
                    seguro, lo pagaremos muy caro dentro de poco.

                    http://es.wikipedia.org/wiki/DRY

            Principio 3: KISS - "Mantenlo Simple, Estúpido!"
                    Hay una frase que dice “la mejor arquitectura es la sencillez”. La sencillez es escalable, si
                    resolvemos pequeños problemas y luego los unimos, será más fácil que hacer un sistema
                    complejo de entrada (así funciona Unix / Linux).

                    http://es.wikipedia.org/wiki/Principio_KISS

            Principio 4: Estándar de Codificación PHP / Zend
                    El lenguaje PHP y su comunidad, por años, no ha tenido ningún referente único para seguir un
                    estándar, por consiguiente los desarrolladores usan o inventan el que más le quede cómodo. La
                    empresa Zend Technologies, principal desarrolladora de PHP (junto al autor original) y
                    creadora de Zend Framework, ha tomado cada vez más protagonismo (principalmente por su
                    framework), por lo que debería ser de ahora en más nuestra referencia a seguir.

                    Evita crear un estándar propio, usa el definido por Zend.

                    HTTP://FRAMEWORK.ZEND.COM/WIKI/DISPLAY/ZFDEV/PHP+CODING+STANDARD+(DRAFT)




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
28 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com




                                    Nota del Autor: si prestas atención verás que en todos los ejemplos las llaves {}
                                    inician a la izquierda cuando es una clase o un método, no se usa el tag de
                                    cierre de php ?>, atributos y métodos privados iniciando con “_”, etcétera.

                                    Bien, todo eso lo define el estándar de Zend, así que te recomiendo que lo
                                    leas y lo sigas al pié de la letra, el estándar nos hará más fuertes ;-)




                             “Evita crear un estándar propio, usa el
                                definido por Zend Technologies”
                        HTTP://FRAMEWORK.ZEND.COM/WIKI/DISPLAY/ZFDEV/PHP+CODING+STANDARD+(DRAFT)




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
29 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            Capitulo 2 - “Introducción a los Objetos”
            Aquí es donde inicia todo, el primer viaje con destino aprender las profundidades de la POO ;-)




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
30 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Un sistema complejo que funciona resulta
                           invariablemente de la evolución de un
                        sistema simple que funcionaba. Un sistema
                            complejo diseñado desde cero nunca
                        funciona y no puede ser arreglado para que
                       funcione. Tienes que comenzar de nuevo con
                              un sistema simple que funcione."
                                                        – John Gall




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
31 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             “Vacuidad: vaciar todos los                               Un niño, cuando empieza a hablar, nos
            conocimientos”                                             demuestra que ya entiende el concepto de
                                                                       “objetos”, empieza a nombrar esas “cosas”:
            Como diría el legendario Bruce Lee, si tienes un
            vaso medio lleno no vas a poder recibir por                       “vaso”,
            completo toda la enseñanza                                              ”agua”,
            que te quiero transmitir, por                                           ”papá”,
            consiguiente, “vaciarse” de
                                                                                    “mamá”,
            todo lo que crees que sabes
                                                                                    ”casa”,
            es lo más importante, más
                                                                                    “guau guau” (“perro”),
            que acumular conocimientos
                                                                                    etc.
            y     luego      simplemente
            rechazar lo nuevo creyendo                                          Todos estamos sumidos en un mundo
            que eso “ ya lo sabes”.                                             que tiene reglas (sepamos o no que
                                                                       existen, nos afectan), como cuando tiramos un
            Así que de aquí en adelante, olvida todo lo que
                                                                       objeto y este cae (gravedad), cuando pisamos
            crees que sabes sobre objetos y empecemos de
                                                                       la cola de un gato y este llora (y probablemente
            cero.
                                                                       nos arañe).
            “La sencillez es la mejor                                  Nos vamos dando cuenta que generalmente no
            arquitectura “                                             manipulamos los objetos directamente ni
            Los “objetos” como concepto -fuera de la                   tenemos un completo control sobre ellos,
            informática- existen desde antes de la                     muchas veces solo interactuamos con ellos, por
            programación (obviamente).                                 más que no queramos que el gato se defienda,
                                                                       este lo hará. Nos damos cuenta que cada uno
            ¿Qué es lo que intenta hacer entonces la
                                                                       tiene dentro una “programación” que le dice
            Programación Orientada a los Objetos (POO)?
                                                                       cómo reaccionar ante determinados estímulos
            Lisa y llanamente intentar simplificar la                  o situaciones, y descubrimos luego que un gato
            complejidad (“simplificar las abstracciones”) y            reacciona distinto de otro gato (a pesar que
            tratar de representar de forma simple lo que               ambos son gatos) y que no es lo mismo la
            vemos y manejamos todos los días… los objetos              reacción de un perro con respecto a la de un
            que nos rodean.                                            gato (a pesar que entre ellos
                                                                       existe una relación que los une
                                                                       como mamíferos).
                  "Controlar la complejidad es la
                  esencia de la programación"                          Por lo tanto, así son los
                  -- Brian Kernigan                                    objetos: pueden ser de un tipo
                                                                       determinado (perro, gato),
                                                                       también pertenecer a una
                                                                       misma familia (mamíferos) y a
                                                                       su vez ser únicos (“el gato llamado Risón”)




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
32 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com




            “Lo más importante es detectar los objetos”
            Entonces, la Programación Orientada a Objetos no es más que eso, detectar los objetos existentes en
            nuestro contexto real y construirlos como si fuéramos “Dios”, dándoles un comportamiento para que
            estos sepan solos cómo reaccionar ante la interacción con otros objetos.

            A esta actividad la llamaremos “diseño” y será cuando debamos
            decidir cómo serán y cómo se comportarán nuestros objetos ante la
            interacción con otros objetos.

            Nada más y nada menos... y hemos logrado empezar a hablar del
            tema sin mostrar -hasta el momento - una sola línea de código ;-)



            En resumen
            Abre tu cabeza, borra todo lo que sabes hasta el momento de objetos y de código, y empecemos de
            cero, es más simple de lo que crees.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
33 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                          "La complejidad es destructiva. Chupa la
                         sangre de los desarrolladores, hace que los
                            productos sean difíciles de planificar,
                         construir y probar, introduce problemas de
                            seguridad y provoca la frustración de
                             usuarios finales y administradores"
                                         -- Ray Ozzie




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
34 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



            Capítulo 3 - “Cómo Pensar en Objetos”
            Veremos en este capítulo cómo detectar los objetos sin preocuparnos aún del código.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
35 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                           "Mucho software hoy día es en cierta
                         medida como una pirámide egipcia con
                        millones de piedras apiladas una encima de
                        otra, sin integridad estructural, construido
                           por fuerza bruta y miles de esclavos."
                         Por Alan Kay (científico de la computación)




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
36 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



            “Lo menos importante es el
            código”
                                                                       Tenemos entonces:
            Lo más importante –por lo menos al principio-
            no es jugar con el código (ya que este podrá                      “Un perro”, el “objeto” propiamente
            funcionar, no dará error, pero conceptualmente                     dicho.
            nuestro sistema no funcionará como un sistema
                                                                              “Es de color negro y blanco”, el color es
            “Orientado a Objetos” ni aprovecharemos todas
                                                                               un atributo del objeto “perro”
            sus virtudes), es detectar los objetos dentro de
            un contexto determinado.                                          “reacciona si le tocan la cabeza”, el
                                                                               comportamiento ante un estímulo
                    “Todo problema está sujeto a un
                                                                               externo.
                    determinado contexto, no existe un
                    diseño que se adapte a todos los                          “mueve la cola”, tiene acciones.
                    posibles contextos”
                                                                              “come”, otras acciones relacionadas
            El código con el que se construyen los objetos                     con su exterior/interior
            es meramente circunstancial, una vez que
            tengamos claro el diseño conceptual, luego será                   “hace caca”, tiene otras acciones que
            seguir la receta a través del manual del lenguaje                  están relacionadas con su interior, y
            de turno.                                                          que posteriormente se exteriorizan de
                                                                               alguna forma.
            “Un niño pequeño”
                                                                       También es importante destacar, un poco más
            Empecemos por el diálogo de un niño que
                                                                       sutil, que existe otro objeto en este escenario y
            recién empieza a hablar (en este caso mi hija):
                                                                       se llama “Micaela”, y además existe (aunque no
                    Micaela, de 5 años, dice: “mira el perro           lo veamos) un contexto (“todo sistema tiene un
                    negro y blanco, se llama Tito, le toco la          contexto, un sistema no puede aplicarse en
                    cabeza y mueve la cola, y si le doy de             absolutamente todos los contextos”) donde
                    comer, al rato, hace caca”.

            Claramente tenemos un objeto de tipo “Perro”
            con características bastante definidas (y
            probablemente con algún problema en sus
            esfínteres).



             “Más importante que codificar es detectar
               los objetos sin preocuparnos -aún- del
                 código que los representará” – EP                     “viven” los objetos y que permite que se genere
                                                                       una interacción entre ambos.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
37 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            “El medio de comunicación”                                        El contexto, los objetos, sus atributos,
                                                                              sus acciones, cuáles pueden ser
            De alguna forma u otra, ambos objetos tienen
                                                                              conocidos por otros objetos y cuales son
            cosas en común: existe un medio que les
                                                                              (o deben ser) naturalmente internos del
            permite comunicarse, pero a su vez ellos tienen
                                                                              propio objeto, para finalmente hacerlos
            los elementos para generar ese “diálogo”, como
                                                                              interactuar como en una obra de teatro
            así también existen “acciones” que son
                                                                              o en un cuento, con varios posibles
            “internas” e “implícitas” de cada uno:
                                                                              principios y finales según la historia que
                   Aunque Micaela –y aún el perro- no lo                     necesitemos contar.
                    entienda, ambos tienen internamente
                    distintos mecanismos de digestión y
                    ninguno controla el mecanismo del
                    otro.
                   El perro, que sabe que cuando está
                    nervioso mueve la cola, no logra
                    entender del todo por qué si Micaela lo
                    acaricia, esta también se mueve.
                    Micaela sabe que si lo acaricia su cola se
                    moverá.



                   Micaela tiene una mano y el perro una
                    cabeza, Micaela tiene acceso a su                  Cuando veamos los primeros ejemplos
                    cabeza, y la cabeza es accesible para              codificados entenderán un poco más de lo que
                    que la mano pueda acariciarla.                     hablo ;-)
            Parece tonto y simple, pero así son los objetos,
            y en esos temas tenemos que pensar cuando
            diseñamos:




                                                Nota del Autor: no, no estoy bajo los efectos de alucinógenos, la POO
                                                tiene más de observación de la realidad de lo que normalmente se cree,
                                                nunca deben diseñar un sistema que “no sea coherente con la realidad”.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
38 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Capítulo 4 - “POO según LOS MANUALES”
            En la era “web” es muy probable que antes de consultar un libro impreso usemos nuestro navegador y
            busquemos material de lectura. Esto no está mal, el problema es que existe mucha información antigua
            o incorrecta, también existen demasiados “charlatanes”, por lo que deberemos ser desconfiados y
            selectivos con lo que leemos.

            Dos fuentes que son confiables y que tenemos más a mano son Wikipedia, principalmente para
            consultar los conceptos fundamentales que se aplican a cualquier lenguaje Orientado a Objetos, y el
            manual oficial de PHP, que aunque es un manual de programación y no de desarrollo (se concentra más
            en la sintaxis que en los conceptos), tiene mucho para enseñarnos (el resto lo haremos a través de este
            libro ;-)).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
39 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



            “La POO según Wikipedia”
            Amén que la introducción conceptual de Wikipedia está bien, en algunas partes puede generar
            confusión o no estar suficientemente explicadas. Intentaremos resaltar algunos puntos fundamentales
            sin reescribir el capítulo original.

            De todas formas, se sugiere primero la lectura del capítulo en Wikipedia

            http://es.wikipedia.org/wiki/POO




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
40 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Depurar código es dos veces más difícil que
                          escribir código, por lo tanto si escribes el
                         código tan inteligentemente como te sea
                              posible, por definición no serás lo
                           suficientemente inteligente como para
                                         depurarlo"




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
41 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Luego de haber leído el capítulo original en                      primera se pensó como funcionalidad
            Wikipedia, quiero resaltar los siguientes puntos                  por un lado y datos por otro, es decir,
            fundamentales:                                                    llamar a una función y pasarle
                                                                              constantemente datos para que los
                1. La POO es un paradigma que tiene sus                       procese, mientras que la POO está
                   orígenes desde antes de 1990 (a partir                     pensada para tener todo integrado en
                   de este año se empieza a popularizar).                     el mismo objeto.
                   Por lo tanto no es ninguna excusa
                   (menos como Desarrollador PHP) seguir                             “En la programación
                   a la fecha desconociendo cómo trabajar                             estructurada sólo se escriben
                   con POO o discutiendo si realmente es                              funciones que procesan datos.
                   útil su adopción.                                                  Los programadores que
                                                                                      emplean éste nuevo paradigma,
                2. “Los objetos son entidades que                                     en cambio, primero definen
                   combinan estado, comportamiento e                                  objetos para luego enviarles
                   identidad”                                                         mensajes solicitándoles que
                                                                                      realicen sus métodos por sí
                3. Fundamental, los beneficios que                                    mismos.”
                   obtenemos usando este paradigma:
                                                                          6. Muy importante es tener SIEMPRE en
                            “La programación orientada a                    claro los conceptos FUNDAMENTALES,
                             objetos expresa un programa                     si no los tienes claros cuando
                             como un conjunto de estos                       programas OO, algo está mal, seguro
                             objetos, que colaboran entre                    errarás el camino que define el
                             ellos para realizar tareas. Esto                paradigma: Clase, Herencia, Objeto,
                             permite hacer los programas y                   Método, Evento, Mensaje, Atributo,
                             módulos más fáciles de escribir,                Estado Interno, Componentes de un
                             mantener y reutilizar.”                         objeto y Representación de un objeto.
                                                                             No dudes en volver a repasarlos todas
                4. La razón de por qué no es necesario que                   las veces que lo necesites, por más
                   todos los objetos que creemos tengan                      experto que te consideres, siempre
                   un id como si fuera una clave primaria                    viene bien una relectura de nuestras
                   de una tabla (con el fin de ubicar un                     bases.
                   objeto en particular):
                                                                          7. Características de la POO: igual que el
                            “De esta forma, un objeto                       punto anterior, es fundamental tener
                             contiene toda la información                    claros estos conceptos cada vez que
                             que permite definirlo e                         desarrollamos, con principal énfasis en
                             identificarlo frente a otros                    el Principio de Ocultación (que es muy
                             objetos pertenecientes a otras                  común confundir con
                             clases e incluso frente a objetos               Encapsulamiento), lo que explica por
                             de una misma clase, al poder                    qué no deberían existir los atributos
                             tener valores bien diferenciados                públicos ni abusar de los setter/getter
                             en sus atributos.”                              (tema que veremos más adelante).

                5. Diferencias con respecto a la                       Si alguno de estos puntos no quedaron claros,
                   Programación Estructurada versus                    sugiero su relectura en la Wikipedia.
                   Programación Orientada a Objetos: la


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
42 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com



            “POO según el manual Oficial de PHP”
            De la misma forma que en el punto anterior, es muy importante hacer una lectura de Referencias del
            Lenguaje (la base para empezar comprender PHP) y posteriormente del capítulo sobre POO en el
            manual oficial, aunque algunos capítulos no aborden en profundidad cada tema (lo cual es entendible
            si comprendemos que hablamos de un manual de sintaxis y no un tutorial para aprender a programar).

            Todos estos temas los veremos más adelante y haré todas las referencias oportunas al manual oficial,
            pero aquí la lista de temas básicos que trata.

            Clases y Objetos (PHP 5)

            Table of Contents

                1.    Introducción
                2.    Las Bases
                3.    Auto carga de Objetos
                4.    Constructores y Destructores
                5.    Visibilidad
                6.    Alcance del operador de resolución (::)
                7.    La palabra reservada 'Static'
                8.    Constantes De la Clase
                9.    Abstracción de Clases
                10.   Interfaces de Objetos
                11.   Sobrecarga
                12.   Interacción de Objetos
                13.   Patrones
                14.   Métodos mágicos
                15.   La palabra reservada 'Final'
                16.   Clonado de Objetos
                17.   Comparación de Objetos
                18.   Reflección
                19.   Type Hinting




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
43 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                           "Medir el progreso de programación en
                         líneas de código es como medir el progreso
                            de construcción de un avión en peso"
                                                          Bill Gates




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
44 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



            Capítulo 5 - “Empezar a plasmar los objetos en un diseNo”
            En este capítulo empezaremos a ver cómo transformar los objetos que detectamos en nuestra
            observación de la “realidad” en algo “informáticamente” palpable.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
45 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Hay dos maneras de diseñar software: una
                        es hacerlo tan simple que sea obvia su falta
                           de deficiencias, y la otra es hacerlo tan
                         complejo que no haya deficiencias obvias"
                                       -- C.A.R. Hoare




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
46 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            “Cómo representar la
            estructura de los objetos”
                                                                       1) “Los Objetos tienen Atributos,
            En un capítulo anterior habíamos hablado de                   Comportamientos y Estados”
            una situación de la realidad donde una niña (mi
            hija) interactuaba con un perro, así que vamos             Todos los objetos tienen
            a ir por partes y tratar de representar lo que             “atributos”,”comportamientos”
            podemos interpretar del texto que está en un               (“métodos”) y un “estado”. Este
            lenguaje natural y nos describe claramente los             último no es más que la
            objetos y sus relaciones:                                  información que tienen los
                                                                       atributos en un momento dado.
                    Micaela, de 5 años, dice: “mira el perro
                    negro y blanco, se llama Tito, le toco la          2) Un perro se llamará “Tito” y otro “Ruffo”,
                    cabeza y mueve la cola, y si le doy de                pero el atributo es el mismo (“nombre”). Si
                    comer, al rato, hace caca”.                           mañana el perro cambia de nombre, lo que
                                                                          cambia es “su estado” y el mecanismo para
            Si nos concentramos en el perro, tenemos que:                 cambiar el estado serán sus métodos
                                                                          (“cambiar el nombre”).
            Atributos

                   Color

                   Nombre

            Comportamiento

                   Se le puede tocar la cabeza

                   Mueve la cola

                   Puede comer

                   Sabe hacer sus necesidades

            Y se desprende prestando atención a la lectura
            del texto que define nuestro contexto.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
47 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



            3) “La clase, un molde para construir objetos”

            Este ejemplo es muy usado para tratar de
            transmitir el concepto que hay detrás.
            Podríamos decir que si “jugáramos a ser Dios”,
            primero definiríamos un diseño de cómo va a
            ser la criatura que queremos crear, haríamos
            un “molde” a partir de ese diseño, y
            posteriormente podríamos crear “vida” con
            similares características, pero que siempre
            serán “objetos únicos”.

            “Crear Personas”

            Por ejemplo, si quiero crear “Personas” diría
            que todas tendrán un sexo (masculino /
            femenino), dos piernas, dos brazos, una cabeza
            y pelo sobre ella (es un diseño simple para un
            contexto simple, si fuera otro el contexto, muy
            probablemente debería cambiar mi diseño).

            “Crear Perros”

            Por ejemplo, podría decir que los “Perros”
            también tendrían un sexo, pero ahora tendrían
            cuatro patas, una cabeza y pelo sobre todo su
            cuerpo.

            Para ambos ejemplos ya cuento con dos
            moldes, el de Personas y el de Perros, por lo
            tanto ahora puedo crear a Micaela y a Tito, pero
            también podría crear a Martina y a Ruffo, por lo
            que tendríamos dos personas y dos perros, con
            características similares, pero que serían a su
            vez    criaturas    únicas, identificables     y
            distinguibles entre las demás criaturas, aún
            entre las criaturas del mismo tipo (aunque se
            llamaran igual y tuvieran los mismos rasgos,
            serían solo parecidos).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
48 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



            4) “Los atributos y comportamientos pueden                 Cómo se debería leer este diagrama:
               ser públicos o privados”
                                                                              Todo lo que se encuentre dentro de la
            Existirá información y comportamientos que                         representación “Perro” es “interno y
            serán conocidos por otros objetos (“acceso                         privado” (invisible para el exterior) y lo
            público”) y esto permitirá que se pueda generar                    que se encuentre “una parte dentro y
            una interacción entre ellos. También existirá                      otra afuera” será nuestra “interfaz”
            información y comportamientos que serán                            con el exterior, los “comportamientos
            internos de cada objeto (“acceso privado”) y no                    públicos” del objeto que serán
            serán conocidos por los demás objetos.                             invocados por los “mensajes” enviados
                                                                               por otro objeto que quiere interactuar
            Un diseño posible para nuestro Perro podría
                                                                               con nosotros.
            ser:
                                                                              Un objeto de tipo “Perro” tiene como
                                                                               atributos su “color” y su “nombre”

                                                                              Dentro de los posibles
    Perro
                                                                               comportamientos públicos de nuestro
    Atributos                                                                  perro podrían ser “comer”, “recibir una
      color                                                                    caricia”, etc.

      nombre                                                                  Dentro de los posibles
                                                                               comportamientos privados de nuestro
    Comportamiento                                                             perro podría ser “hacer la digestión”,
                                     comer                                     que muy probablemente será activada
                                                                               a través de otros métodos (como
      Hacer digestión
                                     Recibir caricia                           “comer”).

                                     Mover la cola

                                     Hacer sus necesidades




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
49 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



            Qué es lo que vería Micaela desde el exterior:

                                                                       Lo que sí sucederá es que Micaela generará
    Perro                                                              indirectamente que se active el mecanismo
                                                                       interno de digestión al darle de comer al Perro
                                                                       (“Micaela le dice al perro que coma”, lo que se
                                                                       debe traducir como “Micaela le envió un
                                                                       mensaje al perro”), pero esto ocurrirá sin que
                                                                       Micaela sepa que sucede, solo podrá apreciar
     Comportamiento                                                    sus resultados cuando el perro haga sus
                                      comer                            necesidades (ya que las necesidades no salen
                                                                       solas).
                                      Recibir caricia
                                                                       Ahora bien, ¿de quién es la responsabilidad de
                                      Mover la cola                    definir todas estas reglas?

                                                                       Si, obviamente, la responsabilidad es nuestra, y
                                      Hacer sus necesidades
                                                                       un diseño será más débil o más robusto de
                                                                       acuerdo a cómo nosotros pensemos que deben
                                                                       reaccionar nuestros objetos a los mensajes que
                                                                       recibirán del exterior y cuanto oculten de sus
                                                                       propios detalles de implementación.

            Solo podríamos interactuar con lo que es
            “público” del diseño, como así lo decidimos.
            Ahora la pregunta sería “¿Qué debería ser
            público y qué debería ser privado?”, bueno,
            intentemos usar el sentido común:

                   el perro necesita poder interactuar con
                    su exterior de alguna forma, pero
                    existirán “detalles” que no conciernen
                    al exterior ni nos interesa que otro
                    objeto pueda modificar a su antojo.

            Por ejemplo, Micaela no tiene por qué saber
            cómo es el mecanismo de digestión de un
            perro, qué órganos entran en juego durante
            todo el proceso, es más, por la vida del perro
            creo que tampoco Micaela debería poder tener
            la potestad para cambiarlo a su antojo (ya que
            seguro estaría en peligro la vida del perro).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
50 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




                                       Nota del Autor: esto es un ejemplo teórico para tratar de transmitir varios
                                       conceptos, como todo diseño, tendrá debilidades y fortalezas, y si
                                       cambiamos de contexto, muy probablemente este diseño no servirá (no
                                       dudo que en este momento estarán pensando “que pasaría si…” y muy
                                       probablemente se encuentren con que algo no se puede hacer... bueno,
                                       vayamos paso a paso y veremos de a poco el horizonte, pero ya les voy
                                       adelantando: no existen diseños que pueda funcionar en absolutamente
                                       todos los contextos posibles, por esta razón es importante definir “el
                                       contexto” de nuestro sistema.

                                                Nota: a menos que estemos hablando concretamente de patrones
                                                de diseño, pero aún así se define en qué contextos se podrían
                                                aplicar y en cuales no.

                                       Por ejemplo: el diseño de una clase Persona no será exactamente el mismo
                                       si estamos hablando de un sistema de reserva de películas, una universidad
                                       con alumnos o un sistema de salud. Tendrán cosas comunes, pero su diseño
                                       no será necesariamente el mismo.

                                       En mi opinión no existe el “100% de reuso puro”, existirán componentes
                                       que dada su naturaleza sí podrán usarse en distintos contextos y otros
                                       directamente no, a menos tal vez que hayamos pensado de entrada que así
                                       debíamos diseñar nuestros componetes: “reusables en varios contextos”,
                                       aunque esto podría aumentar exponencialmente la complejidad del
                                       componente o de los sistemas.

                                       Para más información sobre el apasionante tema sobre “diseño” se
                                       recomienda leer el siguiente artículo de Martín Fowler:




                                                            “¿Ha muerto el diseño?”




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
51 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            En Resumen
            Las clases se construyen en la etapa de diseño donde definimos qué es lo que queremos crear. Lo que
            creamos a partir de ellas es un objeto que “tendrá vida” (será lo que verdaderamente se ejecutará en
            nuestro sistema) y a la vez “único” (podrán existir muchos objetos del mismo tipo, pero podremos
            interactuar con ellos e identificarlos de forma única).

            Dentro de las definiciones de la clase tenemos los atributos y los comportamientos que tendrá nuestra
            creación, algunos de ellos serán públicos y otros serán privados. Todo lo que definamos como público
            será nuestra “conexión” con el exterior y permitirá la interacción entre los objetos. Esta interacción se
            dará a través de envíos de mensajes entre objetos, como por ejemplo “Micaela le da de comer al
            perro”, por lo que existirán dos objetos, uno que puede “comer” y otro que puede decirle al otro “que
            coma” (si no existen estos métodos, el perro directamente no hará nada y estará desconectado con el
            exterior).

            Esto se clarificará cuando empecemos a usar los diagramas UML (similares al diagrama presentado
            anteriormente) y a traducirlos en código concreto y ejecutable.




               Tienes dudas? Quieres hacer una consulta?

               Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
52 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                          "Codifica siempre como si la persona que
                          finalmente mantendrá tu código fuera un
                          psicópata violento que sabe dónde vives"
                                                         -- Martin Golding




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
53 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



            Capítulo 6 - “Introducción a UML”
            De la misma forma que a veces nos apoyamos en un dibujo para tratar de comprender y razonar un
            problema, muchas veces complejo, considero que es fundamental contar con una “herramienta gráfica”
            (para armar “diagramas”) que nos permita discutir y elaborar diseños sin tener que distraernos en los
            superfluos y cirscunstanciales detalles de la codificación según el lenguaje que necesitemos usar.

            Diseñar Orientado a Objetos es independiente del lenguaje de programación, por lo tanto usaremos
            UML, un lenguaje “gráfico” independiente de la implementación.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
54 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        “En las batallas te das cuenta que los planes
                            son inservibles, pero hacer planes es
                                       indispensable”
                                                     - Dwight E. Eisenhower




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
55 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            Aquí es donde entra el Lenguaje Unificado de               “UML y el público objetivo”
            Modelado (UML), y a pesar que existe mucho
                                                                       A pesar que existen reglas
            software para documentar usando diagramas,
                                                                       para    hacer     cualquier
            pero bien podemos decantarnos por una opción
                                                                       diagrama UML, los diseños
            “libre” como ArgoUML (multiplataforma),
                                                                       siempre     deben     estar
            StarUML (win) o Umbrello (lin)
                                                                       sujetos a interpretación y
                                                                       su nivel      de detalle
                                                                       dependerá de nuestro
            “UML, el medio y no el fin en                              “público objetivo”.
            sí mismo”
                                                                       Si vamos a usar un diagrama para presentarles a
            Como bien dice la frase, los diagramas UML son             programadores inexperientes cómo deberían
            el medio y no el fin, sirven para simplificar              desarrollar un sistema, este diagrama debería
            notablemente       las     discusiones   sobre             disponer de la mayor cantidad de información y
            “abstracciones” y mejoran la comunicación                  no dar por sobreentendido nada.
            entre personas, ya sean desarrolladores como
            otros roles dentro de un mismo proyecto. Otra              Por el contrario, si nuestro público son
            de las ventajas es que atrasa la “codificación             desarrolladores “seniors” con experiencia en
            temprana” y facilita estar más tiempo en la                UML, bastará con detallar solo la información
            etapa de diseño.                                           pertinente al problema que se quiere resolver y
                                                                       el resto de información se obviará para evitar
            Existen distintos tipos de diagramas, cada uno             “ruido extra”.
            más adecuado que el otro según la situación (si
            tratáramos con el cliente directamente los                 Un equipo con experiencia en UML debería
            diagramas de Casos de Uso serían lo más                    poder     recibir   cualquier    diagrama       e
            indicado).                                                 implementarlo de forma mecánica sin tener
                                                                       siquiera que razonar el diseño, lo cual significa
            Para lo que a nosotros nos concierne, vamos a              que el diagrama siempre se traduce de la misma
            apoyarnos en ellos para simplificar nuestro                forma, un elemento del diagrama siempre
            razonamiento y poder detectar más fácilmente               tendrá la misma traducción en código, no
            cuando un diseño no es correcto y discutir                 importa el lenguaje que usemos.
            cómo     mejorarlo    y   para    ellos   nos
            concentraremos en los diagramas de clases y
            diagramas de paquetes.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
56 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            “UML es independiente del                                                    Consejo #1
            lenguaje”
                                                                       “No aprendas POO ni te apoyes en libros sobre
            Como bien lo dice la frase, UML es                                   POO que no usen UML”
            independiente del lenguaje. Sirve para
            representar muchas cosas, pero en lo que                                     Consejo #2
            respecta a la POO, cada dato que se impregne
                                                                       “No empieces a desarrollar con POO si no tienes
            en el diagrama podrá ser traducido a cualquier
                                                                       antes –como mínimo- un pequeño diagrama de
            lenguaje que permita implementar el
                                                                          clases explicando la relación entre ellas”
            paradigma de los Objetos. Si el lenguaje de
            turno no lo soportara en un 100%, habrá que                                  Consejo #3
            interpretar el diseño UML y hacer los ajustes
            pertinentes en el código.                                  “Lávate los dientes antes de dormir, cuando te
                                                                            levantes, y luego de cada comida”
            Algunas veces el diagrama no puede
            representarse exactamente en un lenguaje, por
            lo que deberemos ser creativos y quedarnos
            con el concepto que nos busca transmitir el
            diseño (este caso lo veremos concretamente
            con PHP y su problema histórico de representar
            explicitamente los “paquetes”).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
57 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            En resumen
            Los diagramas UML permiten unificar y simplificar la comunicación en un proyecto, como así también
            apoyar el razonamiento en la etapa de diseño de una solución.

            Existen gran variedad de diagramas y son tan importantes como los diagramas MER/DER que se usan
            para diseñar una base de datos. Nadie que desarrolle un sistema se le ocurriría crear una base de datos
            directamente en el servidor sin definir anticipadamente una estrategia en un documento.

            De la misma forma deberíamos pensar a la hora de hacer sistemas Orientado a Objetos.




              Quieres solicitar más información sobre algún punto?

              Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
58 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



            Capítulo 7 - “Cómo representar una clase en UML”
            Empezamos con los primeros pasos en el Lenguaje Unificado de Modelado (UML) y usa las herramientas
            que te sean más cómodas, puede ser ArgoUML , Gliffy, Dia, etc (existen muchos programas más), o
            directamente dibujando en un papel o una pizarra (lo que puedes luego fotografiar y subir a una wiki).

            Lo que importa son los conceptos.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
59 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                          "Primero resuelve el problema. Entonces,
                                     escribe el código"
                                                          -- John Johnson




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
60 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            PHP tiene Estándares: aunque no lo crean,                  Mi primer diagrama UML
            Zend, la empresa que desarrolla el lenguaje y el
                                                                       Definamos un contexto para luego diseñarlo
            framework, tiene definido un documento que
                                                                       con UML:
            especifica los estándares de codificación –que
            para no ser menos- seguiremos al pié de la                 “Una persona tiene nombre, apellido y fecha de
            letra.                                                       nacimiento, cuando se le pregunta qué edad
                                                                       tiene, responde con su edad que calcula en base
                                                                                   a la fecha de nacimiento”
            “Conceptos Generales”
            Primer Regla: de nomenclatura, los nombres de
            las clases son siempre en singular y la primer             Y el diagrama UML debería verse de la siguiente
            letra de cada palabra en mayúsculas                        manera:
            (CamelCase), al revés de los nombres de las
            tablas de una base de datos, generalmente en
            plural y en minúsculas:

                   Tablas en base de datos: personas,
                    animales,usuarios,
                    usuarios_administradores

                   Clases en POO: Persona, Animal,
                    Usuario, UsuarioAdministrador




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
61 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Este diagrama se debe leer de la siguiente                     soporta exactamente, recuerda que
            forma:                                                         UML es independiente del lenguaje)

                                                                          La Sección #3 es para definir los
                                                                           métodos de nuestra clase (CamelCase,
                                                                           igual que con los atributos), la
                                                                           visibilidad de cada uno, los parámetros
                                                                           que pueden recibir y si retornan o no
                                                                           alguna información (para ambos casos,
                                                                           especificando el tipo de dato).



                                                                       Regla: “todos los atributos de una clase
                                                                       son por defecto no-públicos”.

                   La Sección #1 es para definir el nombre            Existe una convención (que casi no se
                    de la clase (como explicamos al                    discute) desde los principios de la POO que
                    principio, usando CamelCase).                      si cualquiera desde el exterior puede
                                                                       conocer y modificar los atributos de un
                   La Sección #2 es para definir los                  objeto, y por ende, su “estado”, todo diseño
                    atributos de nuestra clase (CamelCase,             será débil (este tema lo veremos más en
                    pero a diferencia de las clases, inician           profundidad cuando tratemos el tema
                    con minúscula), la visibilidad de cada             “métodos accesores / modificadores”).
                    uno (el signo “-“ para privado, el signo
                    “+” para público) y qué tipo de dato
                    debería ser (no importa si el lenguaje lo




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
62 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



            Cómo se traduce en código                                  Sección #2 – los atributos de la clase
            Vayamos por partes (dijo Jack, “El                         Según el diagrama, tenemos 3 atributos, todos
            Destripador”), empieza por arriba y sigue                  “privados” (signo “-“) y dos serán de tipo
            secuencialmente hacia abajo, y la traducción se            “String” (cadena de caracteres) y uno de tipo
            hará muy simple y natural.                                 Date (fecha).
            Sección #1 – nombre de la clase

            Siguiendo la nomenclatura del estándar,
            deberíamos primero crear un archivo / fichero
            con el mismo nombre que la clase: Persona.php

            Posteriormente, todo se traduce en:


             <?php
             class Persona
             {
             }


                                                                       Aquí es donde tenemos que interpretar el
                                                                       diagrama y ajustarlo a nuestro lenguaje. Si
                                                                       quisiéramos traducir esta clase a Java no
                                                                       tendríamos problema porque existen “clases
                                                                       base” (ya que en Java “todo es un objeto”)
                                                                       como String, Integer, Date, etc. Pero, como no
                                                                       tenemos esta posibilidad en PHP (aún, espero
                                                                       que en un futuro cercano sí), podemos
                                                                       enfrentarlo de dos maneras, la manera simple y
                                                                       pragmática, o la estricta y dogmática.




                  Estándar de Codificación

                  Como podrán apreciar en el primer código de ejemplo sucede algo atípico: nuestra clase tiene
                  las llaves a la izquierda y no existe el tag de cierre ?>

                  Todo corresponde al estándar de codificación de Zend, particularmente para el último caso se
                  omite cuando el archivo usará solo código PHP y no con HTML embebido.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
63 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



            Versión pragmática                                         Lo máximo que podríamos hacer es:

            <?php                                                      <?php
            class Persona                                              class Persona
            {                                                          {
               private $_nombre;                                          private $_nombre = '';
               private $_apellido;                                        private $_apellido = '';
               private $_fechaNacimiento;                                 private $_fechaNacimiento = '';
            }                                                          }

            Comentario aparte: perfectamente podríamos
            haber usado una traducción directa de los                  Al asignarle un valor por defecto de tipo String,
            atributos y decir que son $nombre, $apellido y             su atributo sería de tipo String y cumpliríamos
            $fechaNacimiento, pero como estamos                        exactamente con el diagrama, a no ser por la
            siguiendo el estándar definido por Zend,                   fecha, porque no tenemos nada parecido a
            usaremos el agregado $_ para todos los                     Date.
            atributos que son “privados”. No olvidar, esto
                                                                       Si tuviéramos la necesidad de definir un Integer,
            no es un problema que debe contemplar UML,
            ya es un problema del lenguaje de turno, en                simplemente asignaríamos un 0 a nuestro
                                                                       atributo, por ejemplo:
            nuestro caso, PHP.

            Versión dogmática                                          private $_edad = 0;

            Por ejemplo, como Java es un lenguaje de                   SUGERENCIA, sean PRAGMÁTICOS: no
                                                                       conviene perder mucho más tiempo con esto ya
            “fuertemente tipado”, cada uno de los atributos
                                                                       que como PHP es de asignación dinámica de
            se traducirían de la siguiente forma:
                                                                       tipos, el hecho que definamos en el comienzo
            Código JAVA:                                               un valor por defecto no asegura que se vaya a
                                                                       mantener, y UML es un medio y no un fin en sí
            public class Persona{
               private String nombre;                                  mismo. El mensaje que nos debe quedar es que
               private String apellido;                                ese atributo debe manejar este tipo de dato, y
               private Date fechaNacimiento;
            }                                                          nosotros como desarrolladores estamos siendo
                                                                       notificados de ello y somos responsables de ver
            Pero como PHP es un lenguaje de “tipado                    luego qué controles deberemos agregar para
            dinámico” no requiere definir inicialmente un              que se cumpla en el resto de la clase.
            tipo para sus variables, el tipo es definido
            dinámicamente cuando se hace una asignación                Por ejemplo, imaginemos lo siguiente: “la
            de valor (y su uso también dependerá del                   documentación que nos entregó nuestro
            contexto en donde se encuentre)                            director de sistemas dice que manejarán
                                                                       valores de tipo Date en el atributo
                                                                       fechaNacimiento” por consiguiente no
                                                                       deberíamos permitir el uso de algo que no sea
                                                                       de tipo Date, así tendrá coherencia el diseño
                                                                       con la implementación. Si el código no respeta
                                                                       el diseño, el código está mal y hay que
                                                                       corregirlo.

            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
64 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



            Sección #3 – los métodos de la clase                       información escrita explicando los posibles
                                                                       detalles o problemas de la implementación, o
            Finalmente, la traducción de los métodos. Aquí             simplemente se hará una reunión para tratar el
            tenemos un método público (signo “+”), que no              tema y sacar dudas.
            recibe parámetros (los paréntesis están vacíos)
            y luego de los “:” representan qué tipo de valor
            retornará (en este caso será un número entero
                                                                       “El Constructor”
            que representará la edad).
                                                                       Si tuviéramos la necesidad de documentar
            El resultado en código sería:                              alguna particularidad
                                                                       del constructor, lo que
   <?php                                                               generalmente se hace
   class Persona
   {                                                                   es agregar un método
      private $_nombre;                                                con el mismo nombre
      private $_apellido;
                                                                       de la clase, lo que
      private $_fechaNacimiento;
                                                                       representaría        “el
      public function decirEdad()                                      constructor” de la clase
      {
          /* calculo la fecha a partir de                              (sintácticamente sería similar a como lo hace
   $_fechaNacimiento */                                                Java y cómo lo hacía PHP4, ya que cambia en
                                                                       PHP5 por la palabra reservada __construct() ).
             return $edadCalculada;

       }
                                                                               Nota: al no existir el tipo Date lo que se
   }                                                                           hace es recibir un parámetro y pasarle
                                                                               el valor al atributo que se encuentra
                                                                               protegido internamente en la clase
            En este ejemplo se puede ver un detalle                            (“atributo privado”).
            importante: ¿cómo y
            cuando se define el                                           El elemento “void”: significa “vacío”, “nada”,
            valor de la fecha de                                          es decir, debemos leerlo como “este método
            nacimiento de la                                              no retorna nada”. En los diagramas UML
            persona?                                                      podemos encontrar que todo lo que no
                                                                          devuelva nada o no tenga tipo, es de tipo
            Respuesta: en ningún                                          “void”. También podemos encontrar que
            momento, el diagrama                                          directamente se omita y no se muestre nada
            UML no dice nada, aquí está supeditado al                  al final del método (eliminado “:void” del final).
            público objetivo de la documentación y a su
            interpretación. Cabe aclarar que cuando se
            entrega un diagrama UML no solo van los
            dibujos, también se acompañan con más




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
65 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



            Persona.php
            <?php
            class Persona
            {
                private $_fechaNacimiento;

                  /**
                    *
                    * @param string $fechaNacimiento 5/8/1973
                    */
                  public function __construct($fechaNacimiento)
                  {
                       $this->_fechaNacimiento = $fechaNacimiento;
                  }
                  public function decirEdad()
                  {
                       return $this->_calcularEdad();
                  }
                  private function _calcularEdad()
                  {
                       $diaActual = date(j);
                       $mesActual= date(n);
                       $añoActual = date(Y);

                       list($dia, $mes, $año) = explode("/", $this->_fechaNacimiento);

                       // si el mes es el mismo pero el dia inferior aun
                       // no ha cumplido años, le quitaremos un año al actual


                       if (($mes == $mesActual) && ($dia > $diaActual)) {
                           $añoActual = $añoActual - 1;
                       }
                       // si el mes es superior al actual tampoco habra
                       // cumplido años, por eso le quitamos un año al actual

                       if ($mes > $mesActual) {
                           $añoActual = $añoActual - 1;
                       }
                       // ya no habria mas condiciones, ahora simplemente
                       // restamos los años y mostramos el resultado como su edad
                       $edad = $añoActual - $año;

                       return $edad;
                  }
            }


            ¿Cómo se prueba?

            $persona = new Persona('5/8/1973');

            echo $persona->decirEdad();




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
66 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            Probando el objeto en un                                   Probando que los objetos son
            contexto determinado                                       únicos
            Nuestra clase ya está lista y definida, ahora
                                                                       Creamos dos instancias a partir de la clase
            habría que probar de crear a partir del “molde”
                                                                       Persona y luego imprimimos en pantalla la
            un “objeto” y probarlo.
                                                                       estructura interna de cada uno de los objetos
                    CRITERIO: como todo debería ser un                 creados con un var_dump.
                    objeto, todos los archivos deberían
                                                                       Como salida obtendremos la radiografía interna
                    tener la misma nomenclatura. Pero en
                                                                       de cada objeto:
                    nuestro caso particular de la web,
                    siempre tenemos una página inicial
                                                                   object(Persona)#1 (3) {
                    “index”, por lo que fijaremos de ahora
                                                                     ["_nombre:private"]=> NULL
                    en más el siguiente criterio: en los             ["_apellido:private"]=> NULL
                    diagramas representaremos la clase               ["_fechaNacimiento:private"]=> string(8) "5/8/1973"
                                                                   }
                    “Index” pero a la hora de
                                                                   object(Persona)#2 (3) {
                    implementarla crearemos el archivo en            ["_nombre:private"]=> NULL
                    minúsculas “index.php” (o de lo                  ["_apellido:private"]=> NULL
                    contrario nuestro servidor web no lo             ["_fechaNacimiento:private"]=> string(8) "5/8/1973"
                                                                   }
                    encontrará) y en su interior podemos
                    crear o no una clase de Index (quedará
                    librado para discutir más adelante).
                                                                       Si prestamos atención, el primero dice:
            Para simplificar y no perder el foco en lo
                                                                       object(Persona) #1 y object(Persona) #2
            importante, probar la clase Persona, haremos el
            mínimo código necesario para index.php.                    Ambos números (#1 y #2) son los
                                                                       identificadores internos del sistema. Por cada
            Listo, creamos nuestro contexto en index.php,
                                                                       objeto que creamos en el contexto de
            donde creamos el objeto unaPersona a partir de
                                                                       index.php (mientras esté ejecutando) se irá
            la clase Persona, definimos su fecha de
                                                                       incrementando secuencialmente y por más que
            nacimiento, y posteriormente le pedimos que
                                                                       los datos de los atributos sean idénticos
            nos diga su edad.
                                                                       (“estado”) estamos hablando que existen en
                                                                       realidad “objetos distintos y únicos”.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
67 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



            En Resumen
            Vimos cómo se representa una clase en UML, que no necesariamente la traducción es literal ya que
            dependemos del lenguaje, pero que UML siempre es independiente, no habla de sintaxis particular y
            siempre está sujeto a una interpretación.




              ¿Algo no quedó claro? No te quedes con dudas

              Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
68 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com



            Capítulo 8 - Ejercicio "Micaela y el Perro"
            Lo más importante es tener bien claros los conceptos, pero fundamental es saber aplicarlos. Iremos
            planteando varios ejercicios que tú mismo puedes hacer y revisar su solución más adelante.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
69 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                       "Programar sin una arquitectura o diseño en
                        mente es como explorar una gruta sólo con
                        una linterna: no sabes dónde estás, dónde
                              has estado ni hacia dónde vas"
                                                           -- Danny Thorpe




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
70 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            Requerimientos
            A partir de todos lo expuesto anteriormente se solicita:

                1. Hacer los diagramas UML de las clases (y codificar cada una de ellas) del ejemplo "Micaela y el
                   Perro" (se sugiere revisar todo el material, ya que hay referencias en varios capítulos).

                2. Crear todas las clases en archivos independientes: Persona.php y Perro.php

                3. Crear un index.php que use las clases que se crearon.

            Atención:

                1. Solo con lo visto hasta el momento, nada de diseños complejos, solo clases involucradas,
                   atributos y métodos.

                2. Evitar toda codificación extra e innecesaria (KISS).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
71 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            Solución                                                      Mi sugerencia es no hacer uso de los
                                                                           _set y _get que incorpora PHP5, ya que
             La idea de cada tarea es aplicar y extender los
                                                                           en la mayoría de los casos –según mi
            conocimientos que se debieron haber adquirido
                                                                           experiencia- debilitan los diseños al
            con la lectura de los capítulos anteriores.
                                                                           generar efectos de “atributos públicos”.
            Estos mismos ejercicios fueron realizados por                  No siempre lo genérico es bueno, como
            alumnos de los talleres a distancia y estos son                en este caso.
            los errores más habituales que se pueden
            cometer:                                                      Si el método retorna algo de tipo
                                                                           “Comer”, por ejemplo
                   A partir de las clases UML se deben                    darComida():Comer, eso significa que
                    generar siempre archivos aparte, por                   el retorno es una clase Comer, por lo
                    clase, con la nomenclatura Persona.php                 cual no es correcto si el retorno en sí es
                    y no persona.class.php o persona.php                   un String, por lo tanto lo correcto es:
                    (debemos usar el Estándar de                           darComida():String.
                    Codificación de Zend)
                                                                          Los atributos deben iniciar siempre en
                   Las llaves “{}” van abajo solo en las                  minúsculas, igual que los métodos
                    clases y métodos, para ningún caso
                    más, ni if, ni while, etc (estándar Zend)             No es necesario especificar el
                                                                           constructor del diagrama si este no
                   Los atributos y métodos privados                       aporta nada relevante.
                    deben llevar delante “_” (estándar
                    Zend), por ejemplo: $_nombre,
                    _hacerDigestion()

                   Siempre realizar “exactamente” lo que
                    se solicita (a menos que solicite
                    explícitamente lo contrario), no más,
                    debemos ajustarnos siempre a los
                    requerimientos que nos solicitan
                    (Principio KISS). Debemos evitar la
                    “sobre-ingeniería” y extender la
                    funcionalidad     de    una     clase,
                    aumentando innecesariamente su
                    complejidad. En un proyecto, donde
                    hay más de un desarrollador es
                    importante que la arquitectura se
                    mantenga “simple”, de lo contrario,
                    cuando crezca, será más costoso
                    mantener el sistema.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
72 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Aplicación del “Principio                                     Siempre cuando diseñen una clase,
            KISS”                                                          “pararse literalmente sobre ella”
                                                                           razonando qué es lo que debería ver o
            Si en una empresa/proyecto para hacer un
                                                                           conocer esta, sin entrar a pensar qué es
            sistema cada desarrollador (con toda la mejor
                                                                           lo que deberían hacer las demás clases.
            voluntad del mundo) agrega un “extra” y trata
                                                                           Tan importante como diseñar qué
            de hacer la “super clase” (agregar funcionalidad
                                                                           hacen es entender qué no deberían
            no solicitada), la complejidad aumentará
                                                                           hacer.
            exponencialmente.

            Es recomendable ajustarse a los                               Seguir el principio de diseño OO: “Una
            requerimientos, a menos que estos digan que                    clase, una única responsabilidad”, si
            deben cubrir todos los posibles errores,                       tiene más de una responsabilidad, debe
            situaciones, etc, pero de todas formas habrá                   estar haciendo más de lo que le
                                                                           corresponde, y deberá descomponerse
            que definir un criterio o un límite.
                                                                           en otra clase.
            Recuerda: un diseño está atado siempre a un
            contexto, si cambia el contexto, muy                          Finalmente, con él o los objetos de más
            probablemente deberá cambiar el diseño. No                     alto nivel, empezar a interactuar con
            existen diseños que sirvan para absolutamente                  los objetos de más bajo nivel, sin
            todos los contextos posibles, por lo tanto, es                 interesar cómo están construidos por
            recomendable hacer un diseño concreto para                     dentro y qué hace su código interno;
            un contexto concreto.                                          solo hay que tomar los objetos y
                                                                           pedirles la información o el
            Sugerencias para enfrentar                                     comportamiento que necesitamos de
            los diseños                                                    ellos (“interfaz pública”).
            En general, tratar de:                                        Y el más importante de todos,
                                                                           Mantener un “Diseño Simple” en todos
                   Empezar a pensar el diseño a partir de
                                                                           los sentidos, evitar complejidad
                    los objetos de más bajo nivel (los más
                                                                           innecesaria. Por ejemplo, puedes tomar
                    simples) y en ese momento “olvidarse
                                                                           la siguiente métrica: si un método no se
                    del bosque” (así no se pierde el foco de
                                                                           puede visualizar en una sola pantalla,
                    lo que se está tratando de abstraer, el
                                                                           hay algo que evidentemente está mal y
                    objeto concreto como entidad
                                                                           hay que descomponerlo en varios
                    independiente).
                                                                           métodos (refactoring), etc.




                                                                              Sugerencia:

                                                                              Prefiere “Simple” sobre “Complejo”




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
73 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Propuesta de Diseño 1
            Para este caso planteo otro posible diseño siguiendo al pié de la letra lo comentado en los capítulos
            anteriores.

            Diagrama UML

            Diagramas usando Netbeans 6.5 + plugin UML




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
74 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



            Traducción de UML a PHP

            Perro.php
            <?php

            class Perro
            {
              private $_color;
              private $_nombre;
              private $_estomagoLleno = false;

                public function __construct($nombre, $color)
                {
                    $this->_nombre = $nombre;
                    $this->_color = $color;
                }
                public function recibirCariciaCabeza()
                {
                  return $this->moverLaCola();
                }
                public function moverLaCola()
                {
                    return 'estoy moviendo la cola!';
                }
                public function comer()
                {
                    $this->_estomagoLleno = true;
                    sleep(5);
                    return $this->_hacerDigestion();
                }
                public function hacerNecesidades()
                {
                  return 'hago caca!';
                }
                private function _hacerDigestion()
                {
                    $retorno = null;

                    if($this->_estomagoLleno){
                        $this->_estomagoLleno = false;
                        $retorno = $this->hacerNecesidades();
                    }
                    return $retorno;
                }
            }




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
75 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com




            Persona.php
            <?php
            class Persona
            {
                private $_edad;
                private $_nombre;

                  public function __construct($nombre, $edad)
                  {
                      $this->_nombre = $nombre;
                      $this->_edad = $edad;
                  }
                  public function darCariciaPerro($perro)
                  {
                    echo $perro->recibirCariciaCabeza() . '<br>';
                  }
                  public function darDeComerPerro($perro)
                  {
                    echo $perro->comer() . '<br>';
                  }
            }




            index.php
            <?php
            require_once 'Persona.php';
            require_once 'Perro.php';

            $persona = new Persona('Micaela', 5);
            $perro = new Perro('Tito', 'blanco y negro');

            $persona->darCariciaPerro($perro);
            $persona->darDeComerPerro($perro);




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
76 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Propuesta de Diseño 2
            Atención con la “sobre-ingeniería”, hay que evaluar si estas mejoras no son demasiadas porque el
            contexto no lo requiere.

            Cambios

                   Se hace más genérico, no es dependiente de un perro, puede acariciar otras cosas que sean
                    “acariciables” (otros animales).

                   Se crea una clase Index para mostrar cómo sería hacerlo 100% POO, usando la invocación sin
                    instancia, directamente ejecutando la clase (más adelante profundizaremos).

                   Las clases nunca imprimen información, siempre retornan. Solo la primer clase que invoca toda
                    la acción del sistema (“Clase Controladora”) hace la impresión que genera la página html
                    (ubicada en el archivo index.php)



            Diagrama UML




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
77 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



            Traducción UML a PHP

            Perro.php
            <?php
            class Perro
            {
              private $_color;
              private $_nombre;
              private $_estomago;

                public function __construct($nombre, $color)
                {
                    $this->_nombre = $nombre;
                    $this->_color = $color;
                }
                public function tocan($lugar)
                {
                    $retorno = null;

                    if($lugar == 'cabeza'){
                      $retorno = $this->_moverCola();
                    }
                    return $retorno;
                }
                private function _moverCola()
                {
                    return 'estoy moviendo la cola!';
                }
                public function comer($comida)
                {
                    $this->_estomago = $comida;
                    sleep(5);
                    return $this->_hacerDigestion();
                }
                private function _hacerDigestion()
                {
                    $retorno = null;

                    if(isset($this->_estomago)){
                        $this->_estomago = null;
                        $retorno = $this->_hacerNecesidades();
                    }
                    return $retorno;
                }
                private function _hacerNecesidades()
                {
                  return 'hago caca!';
                }
            }




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
78 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



            Persona.php
            <?php
            class Persona
            {
                private $_edad;
                private $_nombre;

                  public function __construct($nombre, $edad)
                  {
                      $this->_nombre = $nombre;
                      $this->_edad = $edad;
                  }
                  public function tocar($objeto, $lugar)
                  {
                      return $objeto->tocan($lugar);
                  }
                  public function darComer($objeto, $comida)
                  {
                      return $objeto->comer($comida);
                  }
            }


            index.php
            <?php
            require_once 'Persona.php';
            require_once 'Perro.php';

            class Index
            {
                public function ejecutar()
                {
                    $persona = new Persona('Micaela', 5);
                    $perro = new Perro('Tito', 'blanco y negro');

                        echo $persona->tocar($perro, 'cabeza') . '<br>';
                        echo $persona->darComer($perro, 'carne') . '<br>';
                  }
            }

            $index = new Index();
            $index->ejecutar();




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
79 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com



            En Resumen
            Siempre se pueden plantear más de un diseño y esto quedará a discusión del equipo de trabajo y
            ajustándose a un contexto determinado. Se plantearon un par de diseños que no necesariamente son
            “la única solución posible” y se busca extender la comprensión de los conceptos tratados.




              Encontraste algún error? Quieres enviar una sugerencia?

              Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
80 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Capítulo 9 - Los métodos "getter / setter" o "accesores /
            modificadores"
            He visto mucha documentación que habla sobre el tema de los métodos "getter / setter", o traducido al
            castellano los métodos "accesores / modificadores", y la mayoría se va a los extremos, perdiendo de
            explicar de forma simple la razón de su existencia, y algo más importante, por qué no deberíamos abusar
            de esta práctica.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
81 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Si la depuración es el proceso de eliminar
                        errores, entonces la programación debe ser
                                el proceso de introducirlos"
                                                       -- Edsger W. Dijkstra




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
82 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



            El origen de la necesidad de                               Nosotros, como "desarrolladores
            los "set y get" para los                                   experimentados", nos sentimos molestos
            atributos                                                  por la tontería que acaba de hacer el
                                                                       "estudiante"... ahora la pregunta es, como
            En PHP4 todos los atributos de un objeto son               evitamos que esto suceda?
            siempre atributos públicos, es decir, cuando
            creamos una instancia del objeto a partir
                                                         $unUsuario->nombre = strtoupper($unUsuario->nombre);
            de la definición de la clase, tanto para
            leerlos como para modificarlos.
                                                             if (is_null($unUsuario->clave)){
                                                                $unUsuario->clave="clavePorDefecto";
            Definición de la clase "Usuario" en PHP4         }
            class Usuario{
                var $nombre;                                           Uno de los problemas aquí es que PHP4 no
                var $nombreReal;
                                                                       soporta la definición del "alcance" (o
                var $edad;
                var $clave;                                            también llamada "visibilidad") de los
            }                                                          atributos y métodos, algo habitual en
                                                                       cualquier lenguaje serio de tipo "Orientado
            Creo el objeto "unUsuario":                                a Objetos". Esto hace que -aunque no nos
                                                                       guste- el desarrollador de turno pueda
            $unUsuario = new Usuario();
                                                                       hacer lo que quiera con los atributos de
                                                                       cualquier objeto a su alcance.
            En este momento el usuario está vacío,
            pues sus atributos no tienen ningún valor
            asignado. Por lo tanto, le daremos sentido a
                                                                       Migremos la sintaxis a PHP5
            este objeto:
                                                                       PHP5, consciente de este problema,
                                                                       implementa la definición de "visibilidad" de
  $unUsuario->nombre = "eplace";                                       los atributos y métodos, como lo haría Java
  $unUsuario->nombreReal = "Enrique Place";
                                                                       o .Net. Si hiciéramos una migración
  $unUsuario->edad = "33";
  $unUsuario->clave = "pepe";
                                                                       "mecánica" de nuestro código, este
                                                                       cambiaría la sintaxis a esta forma (ya que la
                                                                       sintaxis "var" pasa a desuso y esta definía a
            Definamos un contexto de                                   los atributos siempre "públicos"):
            ejemplo
                                                                       class Usuario
                                                                       {
            Supongamos ahora que nuestro sistema es                        public $nombre;
            mantenido por varios desarrolladores y que                     public $nombreReal;
            una parte del sistema es mantenida por un                      public $edad;
            "estudiante de programación" que decidió                       public $clave;
                                                                       }
            unilateralmente que cuando le llegue el
            objeto "unUsuario" le pondrá siempre el
                                                                       Ahora disponemos de las siguientes
            nombre en mayúsculas y le colocará una
                                                                       opciones gracias a la nueva sintaxis: public,
            clave por defecto si esta está vacía.
                                                                       private y protected.



            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
83 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            Ahora bien, si queremos que el "estudiante" no             Por un tema de principios de la POO los
            pueda modificar nuestros datos, podemos pasar              atributos de los objetos deben ser siempre
            a colocar todos los atributos como "private":              "privados" (concepto "encapsulación": no son
                                                                       accesibles desde fuera del objeto, solo el objeto
            class Usuario                                              tiene la potestad de usarlos directamente) y se
            {
                                                                       deberán crear métodos públicos que sustituya
                private $_nombre;
                private $_nombreReal;                                  una u otra operación, o ambas, cada vez que la
                private $_edad;                                        situación lo amerite:
                private $_clave;
            }                                                                 un método "setter" para "cargar un
                                                                               valor" (asignar un valor a una variable)
            Listo, ahora cuando el "estudiante" quiera ver o
            modificar un atributo, el sistema le enviará un                   un método "getter" para "retornar el
            error. El problema ahora es que nosotros                           valor" (solo devolver la información del
            queremos que:                                                      atributo para quién la solicite).


                1. La edad se pueda saber y cambiar en                 Veamos cómo se resuelve, paso a paso.
                   todo momento.
                2. Se pueda saber el nombre del usuario,
                   pero no modificarlo
                3. No nos interesa que se sepa el nombre
                   real del mismo
                4. Pero queremos que pueda colocar una
                   nueva clave si el usuario se la olvida,
                   pero no saber la que existe actualmente


            Esto no lo podemos hacer ni teniendo todos los
            atributos públicos como sucedía con PHP4 ni
            restringiendo toda la visibilidad como nos
            permite ahora PHP5.

            ¿Cómo se hace entonces?




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
84 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



            Requerimiento 1                                            Requerimiento 2
                                                                       Poder saber el nombre del usuario pero no
            La edad se puede acceder y modificar en todo               modificarlo, para eso hay que agregar solo un
            momento, por consiguiente se deben agregar                 método get para ese atributo:
            los dos métodos, un "get" y un "set" para ese
            atributo:
                                                                           class Usuario
            class Usuario                                              {
            {                                                                  private   $_nombre;
                private $_nombre;                                              private   $_nombreReal;
                private $_nombreReal;                                          private   $_edad;
                private $_edad;                                                private   $_clave;
                private $_clave;
                                                                               public function getEdad()
                  public function getEdad()                                    {
                  {                                                              return $this->_edad;
                     return $this->_edad;                                      }
                  }                                                            public function setEdad($edad)
                  public function setEdad($edad)                               {
                  {                                                              $this->_edad = $edad;
                     $this->_edad = $edad;                                     }
                  }                                                            public function getNombre()
            }                                                                  {
                                                                                 return $this->_nombre;
                                                                               }
            Pronto, ahora el atributo se puede consultar o
                                                                           }
            modificar no directamente, solo a través de los
            métodos "get / set". En este caso no se nota la            Ahora se puede consultar el nombre pero no
            utilidad, pero pasemos al siguiente                        modificar, pues el atributo no es visible desde
            requerimiento.                                             fuera del objeto, solo a través de los métodos
                                                                       públicos que vamos definiendo.


                Recordatorio                                           Requerimiento 3
                                                                       No nos interesa que se sepa el nombre real del
                Estamos usando el estándar de                          usuario
                codificación definido por la empresa
                Zend. Por ejemplo, los métodos y                       Lo dejamos como está y queda inaccesible
                atributos privados deben iniciar con                   desde fuera del objeto.
                “_” y todas las llaves de métodos y
                clases inician a la izquierda (ninguna
                otra más, como un if, for, etc).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
85 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Requerimiento 4                                            Formalicemos:
                                                                       "Getter/Setter es solo un
            Queremos que pueda colocar una nueva clave
                                                                       tema de conceptos"
            si el usuario se la olvida, pero no saber la que
            existe actualmente
                                                                       Cuando empezamos a aprender a usar Objetos
                                                                       el primer error que cometemos es dejar todos
            Para eso, hacemos lo contrario que con el
                                                                       los atributos públicos, lo que permite que
            atributo nombre, agregamos un método "set"
                                                                       cualquier usuario de nuestra clase pueda hacer
            pero no el "get":
                                                                       y deshacer sin control nuestro objeto
            class Usuario                                              (modificando y consultando sus valores).
            {
               private $_nombre;                                       Generalmente nuestros objetos deberían
               private $_nombreReal;                                   contener determinada información que no
               private $_edad;                                         necesariamente el usuario de nuestro objeto
               private $_clave;
                                                                       debería saber, porque no conviene, o porque
                 public function getEdad()                             directamente no corresponde y permitirle
                 {                                                     acceder a la misma es aumentar
                     return $this->_edad;                              innecesariamente la complejidad del uso del
                 }                                                     objeto.
                 public function setEdad($edad)
                                                                         Regla: "Evitar que el objeto muestre detalles
                 {
                    $this->_edad = $edad;                                           de su implementación"
                 }
                 public function getNombre()                           Por ejemplo: si tu sabes que tu objeto
                 {                                                     "Persona" tiene una fecha de nacimiento y
                    return $this->_nombre;
                                                                       calculas su edad, no deberías poder permitir
                 }
                 public function setClave($clave)
                                                                       que alguien "de afuera del objeto" cambie la
                 {                                                     edad, pues está relacionada con otra
                    $this->_clave = $clave;                            información (fecha de nacimiento) y a partir de
                 }                                                     ella es que se genera (calcularEdad()).
            }
                                                                       Lo correcto sería modificar la fecha de
            Pronto, usando simples métodos podemos                     nacimiento para que el propio objeto la vuelva a
            reforzar el diseño de nuestro objeto,                      calcular.
            restringiendo según nuestra necesidad el acceso
            a sus atributos.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
86 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



                                                                       De lo contrario, ya sería mejor que crearas un
            Los detalles del funcionamiento del objeto son             método común y corriente, asignándole un
            internos, y el usuario del objeto (otro                    nombre claro a su acción.
            desarrollador u otro sistema) no debe ni
            necesita conocerlos. Por consiguiente ya                   Errores más comunes
            tenemos otro caso claro, el atributo "edad" no
            debería poder ser modificado externamente,                 Definir todos los "get" y "set" para todos los
            pero sí consultado cada vez que se necesite.               atributos existentes. Es casi lo mismo que si
                                                                       fueran todos públicos, careciendo de utilidad.
             Si este fuera un atributo público sería
            imposible restringir una operación y habilitar             Lo habitual es que esto no debería suceder,
            la otra. De ahí que nace el concepto de "getter            cuanto más escondamos de nuestro objeto
            / setter", o de "métodos accesores /                       mejor será, pues disminuimos la complejidad de
            modificadores", o como muchos autores se                   su uso y evitamos que cambie a un estado que
            refieren a estos métodos especiales como                   no queremos, y cuando menos se sepa de
            "propiedades" (pero creo que puede generar                 cómo trabaja internamente, más fácil será
            confusiones con el concepto "atributo", pues               poder reutilizarlo en contextos distintos
            muchos otros autores usan las mismas palabras              (deberá ser raro que debas dejar disponible
            indistintamente).                                          todo y no existan algunos que sean solo de uso
                                                                       interno).
            Si tú colocas atributos privados, estos serán solo
            "vistos / accedidos / usados / modificados"                Otro error común es agregarle más lógica que
            dentro de la propia clase. Si tu quieres que               asignar un valor o retornar el valor del
            puedan ser accedidos desde fuera de la clase,              atributo. Si necesitas agregarle lógica, ya dejan
            debes crear métodos públicos que                           de ser "get / set", lo cual es mejor que
            internamente "accedan" a los atributos, pero               cambiemos de nombre y lo dejemos con los
            que los dejarán "resguardados" dentro del                  demás métodos comunes de nuestra clase.
            objeto (no hay que olvidar que en un caso
            pueden hacer una operación u otra, no                      Por ejemplo: si para cambiar el nombre del
            necesariamente ambas).                                     usuario, antes de asignar el valor voy a la base
                                                                       de datos y verifico que no exista otro igual, y
            Recalco, digo "nomenclatura", puesto que los               luego en caso de nombre duplicado genero otro
            nombres de los métodos pueden llamarse como                alternativo, etc, preferiría o desglosar el
            quieras, pero si cumplen con ambas                         método setNombre en varias llamadas a
            definiciones (get/set), cumplirá con la esencia            métodos privados, o directamente crear un
            de la funcionalidad. El tema es que, por                   método nuevo que se llame cambiarNombre,
            convención, se tiende a reconocer así a los                reflejando un proceso fuera del simple get/set.
            métodos que solo sirven para "hacer
            operaciones básicas como si trabajáramos con
            atributos públicos", y que además, no deben
            tener más complejidad que la que describo.



            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
87 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



            Nota: esto es muy a nivel personal, hay
            opiniones encontradas sobre tener una lógica               Trata de seguir las siguientes
            elemental dentro de un set/get o hacerlo tan               reglas
            extenso como necesitemos. Claramente estoy
            en el primer grupo.
                                                                          1. Por defecto, atributos privados

            Como detalle, para que quede más                              2. Usa métodos comunes y no getter/setter
            evidente y visualmente claro                                  3. Si no queda otra opción, usa solo getter
                                                                          4. Si no queda otra opción, usa setter
            Como todo es convención a la hora de definir la               5. Trata de evitar getter y setter a la vez
            forma de trabajo en un entorno de desarrollo,                    (efecto "atributo público")
            es habitual que los atributos siempre vayan
            juntos al principio de la clase e
            inmediatamente -antes de empezar a definir
            los métodos- deberían estar los métodos
            "accesores / modificadores". Lo que se suele
            hacer, pues son métodos muy simples y
            generalmente carentes de mucha lógica (como
            se explica en el punto anterior), tal vez sería
            mejor hacerlos en una sola línea, sin
            indentación:

  class Usuario
  {
    private $_nombre;
    private $_nombreReal;
    private $_edad;
    private $_clave;

      /** getter / setter */
      public function getEdad(){return $this->_edad;}
      public function setEdad($edad){$this->_edad = $edad;}
      public function getNombre(){return $this->_nombre;}
      public function setClave($clave){$this->_clave = $clave;}
  }

                                       Nota

                                       De todas formas no tomar esto más
                                       de un ejemplo, ya que el estándar
                                       oficial de codificación para PHP (el
                                       que define la empresa Zend) no
                                       sugiere en ningún momento esta
                                       práctica.


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
88 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            En Resumen
            El tema no es tan complejo, de forma genérica esta es la explicación de qué es "getter/setter" y para
            qué sirve y cómo se usan.

            También quiero destacar que a pesar de existir esta técnica, no quiere decir que deba ser usada o que
            su uso esté completamente permitido. Hay que entender que la POO no debería hacer uso de de los
            getter y setters ya que tendríamos acceso de forma directa al "estado del objeto" (la información que
            tienen los atributos de un objeto) y permitir el acceso o modificación genera el mismo efecto de
            manipulación que si fuera una operación de "corazón abierto".

            Nuestro objeto debería estar protegido del exterior y no permitir tener acceso directo a sus atributos,
            y trabajar siempre sobre sus métodos ("los métodos definen el comportamiento del objeto").

            En caso de no poder hacerlo, se podría priorizar disponer de "get" (obtener valor de un atributo de
            forma directa) y no "set" (modificar un valor directo de un atributo), y en el peor de los casos, tener un
            uso muy controlado de los "set".

            Para más información sobre diseño OO, discusiones teóricas, buenas prácticas, etc, consultar escritos de
            gurúes como Martín Fowler.




              Quieres solicitar un ejemplo adicional?

              Ingresa a http://usuarios.surforce.com




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
89 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



            Capítulo 10 - “Cómo representar las Relaciones entre clases en
            UML”
            Definir las relaciones entre las clases es la parte medular de la POO y donde verdaderamente
            construimos el Diseño OO. Es importante hacer un buen diseño individual de clases, pero más aún saber
            qué significa cada relación, cuando se deben usar y que impacto tiene sobre todo el sistema.




                       IMPORTANTE

                       Aquí entenderemos por qué considero             FUNDAMENTAL     estar apoyado por
                       diagramas para poder visualizar, razonar y discutir un diseño OO. Las relaciones, el
                       significado y sus consecuencias son el corazón de la disciplina. Por ejemplo, nadie
                       concibe enseñar Base de Datos sin empezar primero por los diagramas de relaciones
                       DER/MER.




            Empecemos con las relaciones más básicas y fundamentales: “la dependencia y la asociación”




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
90 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                       "Unas buenas especificaciones incrementará
                        la productividad del programador mucho
                          más de lo que puede hacerlo cualquier
                                 herramienta o técnica"
                                                             Milt Bryce




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
91 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com




            La Relación de Dependencia                                 Todos los diagramas tienen varias
                                                                       interpretaciones, este en concreto nos dice
            Definición: “es una relación de uso entre dos
                                                                       que:
            entidades” (una usa a la otra)
                                                                              La clase A depende de la clase B
            La relación de dependencia es cuando una clase
            depende de la funcionalidad que ofrece otra                       La clase A usa la clase B
            clase. Si lo vemos del punto de vista “Cliente /
            Servidor” (existe una entidad que necesita de                     La clase A conoce la existencia de la
            un “servicio” y otra entidad que lo provee), se                    clase B, pero la clase B no conoce la
            puede decir que una clase es “cliente” del                         existencia de la clase A (es lo que
            servicio de otra clase.                                            significa el sentido de la flecha)

            Esta es la relación más básica entre clases y a su                Todo cambio que se haga en la clase B,
            vez comparada con otro tipos de relaciones, la                     por la relación que hay con la clase A,
            más débil.                                                         podrá afectar a la clase A.

            Representación UML                                         Por eso también se le dice “relación de uso”, la
                                                                       clase A “usa” la clase B.
            La representación en UML es una “flecha
            punteada” o “discontinua” que va desde la clase
            “cliente” del servicio/funcionalidad hasta la
            clase que ofrece el “servicio/funcionalidad”.

            Un diagrama genérico sería:




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
92 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



            Cómo se traduce a código                                   Presta especial atención en el “require_once”,
                                                                       ya que esta sentencia está representando la
            Solo existen dos situaciones posibles                      “dependencia” con otra clase al requerir su
                 1. En un método de la clase A instancio un            fuente. Tomando el código fuente de una clase
                    objeto de tipo B y posteriormente lo               y siguiendo todos sus require / include
                    uso.                                               podemos determinar la dependencia con otras
                                                                       clases y reconstruir el diagrama (ingeniería
                 2. En un método de la clase A recibo por              inversa).
                    parámetro un objeto de tipo B y
                    posteriormente lo uso.

            Por consiguiente, completemos los diagramas
            de ejemplo:




            Caso 1 – instancio un objeto
            B dentro de un método de A


            Y traducido a código será:

            A.php:

            <?php

            require_once 'B.php';

            class A
            {
               public function mostrar()
               {
                    $b = new B();

                      /* etc */
                 }
            }




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
93 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            Caso 2 – recibo por                                        Finalmente, la “flecha punteada” representa
            parámetro de un método de                                  que es una “relación débil” en contraposición a
            A un objeto B                                              la siguiente relación, la “asociación”, que se
                                                                       representa con una “flecha continua” y
                                                                       representa una relación “más fuerte”.




            A.php
            <?php

            require_once 'B.php';

            class A
            {
               public function mostrar(B $b)
               {
                    echo $b;

                      /* etc */
                 }
            }

            Varios detalles a tener en cuenta:

                    En el diagrama UML se representa el
                     parámetro de esta forma b : B, lo cual
                     debe ser leído en el orden variable :
                     Tipo, pero dependiendo del lenguaje, la
                     traducción generalmente es al revés:
                     Tipo $variable (como se puede
                     observar en el ejemplo con el método
                     “mostrar(B $b)”).

                    Aparece por primera vez el Type
                     Hinting (“indicando el tipo”) que es
                     incorporado en PHP5 (imitando muchos
                     lenguajes de tipado fuerte como Java) y
                     que permite –sin llegar a perder el
                     tipado dinámico- reforzar el diseño al
                     solo permitir que ingresen por
                     parámetro objetos del tipo que
                     especifiquemos (ampliaremos más
                     adelante).


            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
94 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            La Relación de Asociación                                  Representación UML
            Definición: “es una relación estructural entre             La representación en UML es una “flecha
            entidades” (una entidad se construye a partir de           continua” que va apuntando desde la clase
            otras entidades)                                           “compuesto” hasta la o las clases
                                                                       “componentes”.
            La relación de asociación es cuando una clase
            tiene en su estructura a otra clase, o se puede            Un diagrama genérico será:
            decir también que se construye una clase a
            partir de otros elementos u objetos. Si lo
            codificáramos esto se representa como un
            atributo que es una instancia de otra clase.

            Esta relación se debe entender como la
            actividad de construir elementos complejos a
            partir de otros elementos más simples, y
                                                                       Nuevamente, los diagramas tienen varios
            justamente, la verdadera esencia de la POO.
                                                                       mensajes que nos transmiten:
            Por ejemplo
                                                                             La clase A depende de la clase B
            Un auto está compuesto por un motor, un
                                                                             La clase A está asociada a la clase B
            tanque de combustible y una antena de radio,
            por lo tanto tendríamos:                                         La clase A conoce la existencia de la
                                                                              clase B, pero la clase B no conoce la
                   un objeto Auto y como atributos del
                                                                              existencia de la clase A (sentido de la
                    mismo tendríamos los objetos Motor,
                                                                              flecha)
                    Tanque y Antena.

            Lo interesante notar aquí es que el Auto no                      Todo cambio que se haga en la clase B,
            conoce los detalles internos de cada uno de sus                   por la relación que hay con la clase A,
            componentes, simplemente se construye a                           podrá afectar a la clase A.
            partir de ellos pero cumplen el “Principio de
            Ocultación”, lo cual fortalece el diseño al
            desconocer detalles internos que pueden
            obligarlo a depender fuertemente de cómo
            están implementados.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
95 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



            Cómo se traduce a código

            Creando una clase A que tiene como atributo un                Lo ideal sería que en la misma
            objeto de tipo clase B.                                        definición del atributo poder hacer la
                                                                           creación de la instancia del objeto sin
            A.php
            <?php
                                                                           depender de un constructor (como
                                                                           sucedería en Java), pero el detalle aquí
            require_once 'B.php';                                          es que PHP no soporta la creación de
            class A                                                        instancias en la definición de atributos,
            {                                                              solo podríamos hacer una asignación
               private $_b;
                                                                           directa si el atributo es un array, pero
                 public function __construct()                             no crear una instancia (con “new”). Solo
                 {                                                         podremos crear las instancias de
                     $this->_b = new B();
                 }
                                                                           nuestros atributos en el constructor o
            }                                                              dentro de los métodos de la clase.

            $a = new A();




            Varios detalles a tener en cuenta:

                    En el diagrama no se especifica en la
                     clase A, en la zona de atributos, el
                     atributo “b”, pero se puede inferir de la
                     relación representada en el diagrama.
                     Por lo tanto está sujeto a decisión de
                     cada uno agregar o no más detalle en el
                     diagrama (lo cual dependerá siempre
                     del público objetivo del mismo).

                    Como no se especifica, tampoco parece
                     decir nada sobre su visibilidad:
                     mantendremos siempre el criterio que
                     los atributos por defecto son siempre
                     “no públicos”, por lo tanto por defecto
                     son “privados” (más adelante veremos
                     otras posibilidades).




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
96 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



            UML del ejemplo del Auto


            Auto.php
            <?php

            require_once 'Motor.php';
            require_once 'TanqueCombustible.php';
            require_once 'AntenaRadio.php';

            class Auto
            {
               private $_motor;
               private $_tanqueCombustible;
               private $_antenaRadio;

                 public function __construct()
                 {
                     $this->_motor = new Motor();
                     $this->_tanqueCombustible = new TanqueCombustible();
                     $this->_antenaRadio = new AntenaRadio();
                 }
            }

            $auto = new Auto();



            Los comentarios sobre la lectura de las flechas y
            los sentidos son los mismos que en los casos
            anteriores:

                    Según el sentido de las flechas, el Auto
                     conoce a sus componentes y los
                     componentes no conocen al Auto.

                    Si los componentes cambian, afectan al
                     Auto, ya que este está asociado a ellos,
                     no así al revés.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
97 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



            Variaciones de Asociación:                                 Ejemplos de Agregación y de Composición
            Relación de Agregación y
            Relación de Composición
            Se puede especializar la relación “asociación”
            en dos tipos más (note que las flechas siguen
            siendo continuas pero agrega un rombo en su
            inicio).

            Relación de Agregación
                                                                         “La Universidad agrupa muchos Alumnos”
            Es una relación de asociación pero en vez de ser
            “1 a 1” es de “1 a muchos”, la clase A agrega
            muchos elementos de tipo clase B




                                                                           “El círculo está compuesto por puntos”
            Relación de Composición                                     Al existir una relación de vida, no se concibe
                                                                        que existan puntos sueltos sin estar en una
            Similar a la agregación, solo aporta semántica a                           figura geométrica
            la relación al decir que además de “agregar”,
            existe una relación de vida, donde elementos de
            B no pueden existir sin la relación con A.

            Desde el punto de vista de muchos lenguajes
            (como Java o PHP) esto no necesariamente
            genera ningún cambio en el código, pero puede
            ser tomado como parte de la documentación
            conceptual de cómo debería ser el diseño del
            sistema.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
98 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com




            Ejemplo de traducción a código                             Ejemplo de traducción a código

            La forma de representar ambas variantes es                 Universidad.php
            simple y como en todos los casos, mecánica.
                                                                       <?php
            El elemento del lenguaje que por defecto nos               require_once 'Alumno.php';
            permite contener varios elementos es el array,
            por lo tanto del diagrama se desprenden                    class Universidad
                                                                       {
            (aunque no esté explícitamente) que                           private $_alumnos = array();
            tendremos:
                                                                           public function add(Alumno $alumno)
                1) Un atributo de tipo array para contener                 {
                                                                              $this->_alumnos[] = $alumno;
                   todos los elementos                                     }
                                                                       }
                2) Por lo menos un método para agregar
                   los elementos al array, que                         $universidad = new Universidad();
                   generalmente se representa con un                   $universidad->add(new Alumno());
                   simple “add” (que como siempre queda
                                                                       $universidad->add(new Alumno());
                   sujeto a variar según nuestro criterio).
                                                                       $universidad->add(new Alumno());
            Teniendo en cuenta lo anterior, podría apuntar
            mi diagrama a un público que no le fuera                   /*
                                                                        * Esta universidad contiene 3 alumnos
            evidente su implementación, por lo tanto                    */
            podría ser tan específico cómo:




            Aunque podría pecar de redundante, ya que el
            diagrama original ya representa toda esta
            implementación.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
99 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



            ¿Qué relaciones se deberían                                Ejemplo de relación cíclica
            evitar?
            Las relaciones bidireccionales y las relaciones
            cíclicas, ya que la visibilidad es en ambas partes
            (A y B) y un cambio en una clase genera un
            impacto en la otra y viceversa, logrando una
            inestabilidad muy peligrosa.

            Ejemplo de cómo se representa una relación
            bidireccional




                                                                       Creo que es evidente el problema sin necesidad
                                                                       de codificar el ejemplo, un cambio en A afecta a
            ElHuevoOLaGallina.php
            <?php                                                      C, como afecta a C, también afecta a B, que a su
                                                                       vez afecta a A… y sigue.
            class A
            {                                                          Caso de Ejemplo
               private $_b;

                 public function __construct()                         "¿Qué sucedería si tenemos una clase Curso y
                 {                                                     otra Profesor? El profesor puede impartir
                    $this->_b = new B();                               varios cursos y un curso puede tener varios
                 }
            }                                                          profesores. ¿Cómo haríamos las relaciones?
                                                                       ¿Dos flechas de agregación, una de Curso a
            class B
                                                                       Profesor y otra de Profesor a Curso?"
            {
               private $_a;
                                                                       Aquí es cuando entra la "decisión de diseño" en
                 public function __construct()                         base al análisis de lo más conveniente según el
                 {                                                     problema que queremos resolver y de evitar
                    $this->_a = new A();
                 }                                                     "todo lo posible" hacer relaciones cíclicas /
            }                                                          bidireccionales.

                                                                       La sugerencia es "deberíamos optar por uno de
                                                                       los dos diseños" (no ambos) de acuerdo a la
                                                                       navegación que sea más conveniente de
                                                                       acuerdo a las necesidades del sistema, qué
                                                                       información requerirá con más frecuencia.




            SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
            Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
100 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Si va a ser más frecuente buscar los cursos de
             un docente o si a partir de un docente vamos a
             necesitar saber sus cursos.

             Aún eligiendo uno u otro diseño, siempre
             podremos "navegar" por ambas formas, solo                  Confusión común
             que una va a costarnos más que la otra.                    A veces podemos cometer el error de
                                                                        decir "cíclicas" cuando deberíamos
             Si tenemos Curso -> Profesor
                                                                        decir "bidireccionales", en sí el efecto
                    Se resuelve directamente si                        es el mismo, solo que en bidireccional
                     necesitamos los profesores de un curso.            no hay un ciclo porque es una relación
                                                                        de 2 clases ("en dos direcciones") y para
                    Pero, para obtener de un docente                   hacer una relación "cíclicla" se necesita
                     cuales son sus cursos, deberíamos                  por lo menos 3 clases para poder hacer
                     recorrer todos los cursos para recién              un ciclo.
                     saber qué cursos tiene asignado.

             Siempre, La última alternativa debe ser optar
             por una relación bidireccional ó cíclica, porque
             aumentas problemas y costos de desarrollo.



             Comentario final : Imaginar cómo sería el
             funcionamiento de un sistema con relaciones
             bidireccionales y a su vez cíclicas entre varias
             clases… lo más parecido a un "Castillo de
             Naipes" ;-)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
101 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Resumiendo rápidamente                                     Por ejemplo:
             algunos conceptos
                                                                              1
             complementarios
                                                                              1..*

             “Navegabilidad”                                                  0..*

             La lectura que debe hacerse al interpretar los                   3..14
             diagramas es:
                                                                        Donde en el primer caso decimos que en A
             A -> B                                                     veremos siempre un objeto de B, en el segundo
                                                                        caso “uno o muchos”, en el tercer caso
                     “B no tiene idea de A”                            “ninguno o muchos” y el en último caso “de 3 a
                                                                        14”.
                     “A puede invocar métodos de B, pero
                      no al revés”                                      Por ejemplo, podrías decir que tienes una
                                                                        Escuela -> Alumnos, entonces podrías agregar a
             A–B                                                        la flecha:
                     Bidireccionalidad: “A ve a B, pero en                   1..N
                      algún momento B ve a A”
                                                                              0..N

                                                                        Primer caso, significa que en algún momento la
             “Definición de Roles”
                                                                        escuela ve 1 o más alumnos (N), pero si haces
             Las relaciones tienen nombre: “tiene”,                     el segundo caso, estás diciendo que en algún
             “contiene”, “fabrica”, etc.                                momento la escuela puede que no tenga
                                                                        alumnos.
             A -tiene-> B
                                                                        Imagina una relación Esposo -> Esposa, podría
             Y es parte de la documentación especificar los
                                                                        ser 1..1, ya que si haces 1..2 ya serías bígamo
             roles de cada relación para ayudar a su
             interpretación y codificación posterior.
                                                                        ¿Cómo nos afecta cuándo debemos traducilo a
                                                                        código? Que si tienes 1..1 debes controlar que
             “Multiplicidad”                                            no pueda suceder (o que de error) si alguna vez
                                                                        no se cumple esta regla.
             Parte de la documentación de UML, en una
             relación A->B, poder especificar la cantidad de            Es un elemento más que se puede agregar en
             objetos de B que se pueden ver en A                        la documentación y que aporta información a
                                                                        quién tiene que interpretar el diagrama y
                                                                        generar el código a partir de él.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
102 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Resumen
             Vimos cómo se representan las relaciones básicas entre las clases, cómo la dependencia es una relación
             más débil que la asociación, y cómo la agregación es una variante de asociación, y que la composición
             se diferencia de la agregación solo por “semántica”.

             Fundamental es entender la visibilidad entre las clases, el sentido de las relaciones, y por qué es
             importante que estas se den de forma acotada y medida, ya que existir flechas que salgan hacia todos
             lados, de forma bidireccional o cíclica, generan que nuestro sistema sea completamente inestable y con
             un alto costo de mantenimiento, ya que cualquier cambio en una clase generará un impacto contra las
             demás clases del sistema.

             De aquí en más se empezará a entender que aprender POO o diseñar un sistema OO no puede hacerse
             sin plantear un diagrama UML analizando meditadamente las relaciones que deben existir entre las
             clases, ya que es la única forma de graficarlas y visualizarlas con facilidad.

             Tranquilos, sobre estos temas vamos a ir presentado ejercicios de ejemplo con sus soluciones a partir de
             varios capítulos a continuación, ya que este es un tema medular ;-)




                Quieres bajar el código fuente de los ejemplos?

                Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
103 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



             Capítulo 11 - Ejercicio "Micaela, el Perro y la Escuela”
             Ampliemos progresivamente los ejercicios prácticos aumentado gradualmente la complejidad.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
104 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




                        "Cuando se está depurando, el programador
                           novato introduce código correctivo; el
                           experto elimina el código defectuoso"
                                                            -- Richard Pattis




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
105 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Requerimientos
                                                                        Se espera
             Partiendo como base el problema presentado
             anteriormente, ahora se agregan los siguientes             Que el Index esté representado en los
             requisitos:                                                diagramas y ser la "Clase Controladora" que
                                                                        inicia el sistema), y ninguna clase puede
             "Micaela, además de tener un perro e                       imprimir por su cuenta (hacer un “echo”), solo
             interactuar como vimos, ella va a la escuela               Index (todos los métodos deben retornar datos
             'Dos Corazones' junto a 5 niños más. Uno de                hacer ningún tipo de impresión).
             esos niños es hermana de Micaela y se llama
             Martina (3 años), ambas son dueñas del mismo
             perro. Tienen un amigo que se llama Marcos (6
             años) y él es dueño de un gato de muy mal                     Explicación: “Controladora”
             carácter, que si le tiran de la cola, es seguro que
             araña!"                                                       Se dice “clase controladora” a una clase que toma
                                                                           el control de la solución de un problema o
             Guía                                                          situación concreta desde una visión de alto nivel.
                                                                           Generalmente a partir de ella se crean y usan la
                                                                           mayor parte de los objetos involucrados en la
             Primero                                                       solución.

             - Representar las relaciones entre las clases
             Index, Persona y Perro.

             Segundo

             - Representar la Escuela, que debe poder
             contener a todos los niños de la letra.

             - Representar la relación de "hermano" entre
             Micaela – Martina.

             - Representar el Gato

             - Usar toString() (ver manual) para que cada
             objeto sepa cómo convertirse a "cadena de
             texto".

             - Fundamental, se hará más hincapié que el
             diseño y código sea KISS, cuanto más código no
             solicitado se encuentre, más puntos se
             perderán.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
106 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Solución
             La idea de cada tarea es aplicar y extender los conocimientos que se debieron haber adquirido con la
             lectura de los capítulos anteriores. Se define un nuevo contexto para evaluar la evolución del lector.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
107 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             “Errores Comunes”                                              mundo, y recién “la visión de bosque”
                                                                            la tenemos cuando nos paramos sobre
             Estos fueron los errores más comunes que han
                                                                            un “index.php” (o el nombre de turno).
             cometido alumnos en cursos a distancia:
                                                                           Olvidar representar en código las
                    El constructor demasiado atado al
                                                                            flechas del diagrama UML: hay que
                     contexto del problema: he visto casos
                                                                            entender que –por ejemplo- si desde
                     donde en el constructor de la Persona
                                                                            index hacemos “require_once” a 4
                     se agrega la posibilidad de recibir un
                                                                            clases, si o si, significa que hay 4 flechas
                     “hermano”. La sugerencia es que el
                                                                            hacia esas clases, y viceversa, si hay 4
                     constructor sea siempre simple y que
                                                                            flechas desde Index, debemos crear 4
                     contenga la mínima información que
                                                                            “require_once” en Index.
                     represente a la clase para crearla,
                     como podría ser el nombre y el apellido,              Confundir desde donde hacer los
                     tal vez la fecha de nacimiento, no                     “require_once”: debemos entender
                     mucha información más. Nuestra                         que PHP “suma” todos los fuentes
                     decisión luego es, si la persona al                    como uno solo y luego lo ejecuta, por lo
                     crearse no cuenta con su fecha de                      tanto, si colocamos todos los
                     nacimiento, ¿permito que se pueda                      “require_once” solo en el index, el
                     crear? ¿O requiero esa información                     sistema funcionará, pero no es lo
                     siempre? De la misma forma considero                   correcto. Cada clase debe mantener
                     que definir un hermano estaría                         sus relaciones de acuerdo al diagrama,
                     separado de la creación de la persona,                 ya que mañana funcionará en otro
                     por lo tanto sería más conveniente que                 contexto y ella debe saber qué clases
                     si tiene un hermano, poder hacer esa                   necesita para funcionar. Si todo está en
                     relación con un método posterior                       Index, esto no representa las
                     (agregarHermano() o setHermano(),                      relaciones desde la clase correcta.
                     según lo que necesitemos hacer).                       Tampoco es problema que las flechas o
                                                                            “require_once” se repitan (el mismo
                    Comprender la utilidad de Index, más
                                                                            “_once” hace que solo tome la primera
                     allá de lo evidente: index.php podría
                                                                            invocación y el resto se ignore). Por lo
                     ser mañana admin.php, no importa su
                                                                            tanto deben ir desde Escuela hacia
                     nombre, lo que importa es que ese es el
                                                                            Persona y desde Persona hacia sus
                     punto de partida donde construimos la
                                                                            mascotas.
                     solución a nuestro problema,
                     implementamos nuestros                                No respetar el estándar de codificación
                     requerimientos, juntando todos los                     de Zend, en particular el uso de las
                     objetos que implementamos y                            llaves {} para los métodos y las
                     empezamos a hacer que interactúen                      sentencias internas. Las llaves inician a
                     para que trabajen para nosotros. Esto                  la izquierda solo cuando es una clase o
                     nos da una idea de que cuando                          un método, en ningún otro lado más.
                     trabajamos diseñando una clase nos
                     tenemos que olvidar del resto del

             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
108 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



                    No hacer “validación de tipo” (“Type                  Se presentan algunos casos de
                     hinting”): en el caso de la Escuela, al                “desborde de ingeniería”. Hay que
                     agregar Personas, validar que solo se                  recordar el Principio KISS, por lo tanto
                     puedan agregar del tipo la clase                       debemos realizar las siguientes
                     “Persona” y no otro, lo mismo para el                  preguntas:
                     caso en que el diseño de Persona fuera
                     “agregar” Mascotas (refuerza el diseño,                    o   ¿Si para implementar un
                     es más robusto ante situaciones no                             ejercicio tan acotado necesito
                                                                                    tanto código, para un proyecto
                     esperadas).
                                                                                    real cuando más necesitaré?
                    Los atributos van siempre privados
                                                                                o   ¿Podré manejar toda esa
                     (99,99% de los casos), tanto por UML
                                                                                    complejidad?
                     como por código.
                                                                                o   ¿Cumpliré los tiempos de
                    Auto relación Persona -> Persona: a
                                                                                    entrega?
                     pesar que una persona tenga elementos
                     de tipo Persona, no hace falta en la                       o   ¿Y si trabajo en equipo? ¿seré
                     clase Persona agregar un require_once                          lo suficiente claro como para
                     hacia Persona.                                                 que otro integrante de mi
                                                                                    equipo pueda seguirme y
                    Evitar relaciones cíclicas: se vieron
                                                                                    repartirnos todo el trabajo? ¿o
                     diseños que planteaban que la Mascota
                                                                                    debo hacerlo todo yo porque
                     tuviera una colección de Dueños. En sí
                                                                                    no entienden lo que hago?
                     el diseño no está mal a menos que
                     genere una relación cíclica entre las                      o   Hacer las cosas complicadas no
                     clases, es decir, Persona ve a la Mascota                      es una virtud, hacer simples las
                     y la Mascota a la Persona (A<->B), por lo                      cosas complicadas debería ser
                     tanto cualquier cambio en una clase                            el verdadero arte y objetivo en
                     afecta a la otra y así sigue en ciclos. Por                    nuestra actividad como
                     lo tanto, este diseño debería evitarse                         desarrolladores profesionales.
                     para anular la relación cíclica (o
                     romperla de alguna forma).

                    El toString es un método reservado
                     __toString: PHP5 fija para varios
                     métodos especiales (constructor,
                     destructor, toString, etc) una sintaxis
                     distinta, le agrega “__” (dos guiones
                     inferiores) al principio del método. Por
                     lo tanto, para que toString funcione hay
                     que implementarlo así, de lo contrario
                     no funcionará al hacer echo $persona;


             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
109 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



                 1) El ejercicio busca llevar al extremo las                  Para no perder foco en las relaciones
                    herramientas que disponemos                               entre los elementos y confundirse con
                                                                              todas las flechas, se omite
                 El ejercicio busca doblar de alguna forma las                intencionalmente en este ejemplo la
                 herramientas que disponemos en la
                                                                              clase Index (ver ejemplo completo más
                 actualidad para con la práctica darnos                       adelante).
                 cuenta que nos faltan elementos para
                 representar toda la realidad que tenemos                     ¿Cómo se probaría este diseño y
                 delante. Por consiguiente, cuando veamos                     verificar que cumpla con la letra?
                 las restantes relaciones entenderemos
                 cómo terminar de armar un diagrama más
                 completo.
                                                                        Auto-relación "Persona"
                 2) Tarea 2 – propuesta de diseño 1
                                                                        Si tú eres "Persona" y tienes una relación con (otra)
                     En este caso se usa la herramienta                 Persona, se dice que tienes una auto-relación, por
                     StarUML y vamos a representar la                   lo tanto se podría representar con una flecha que
                     relación “hermano” con un atributo                 sale de Persona y vuelve otra vez a la clase
                     simple de tipo “Persona”.                          Persona. Como poder, se puede hacer y está
                                                                        permitido, pero a veces por claridad y evitar tantas
                     Tener en cuenta en muchas veces se
                     ven “flecha de agregación” (con el                 flechas, se deja solo lo necesario de lo que quieres
                                                                        comentar / documentar, por lo tanto si tienes un
                     rombo en su inicio) sin la punta -> pero
                                                                        atributo de tipo Persona se sobre-entiende que es
                     el significado es el mismo.
                                                                        una auto-relación, lo mismo, tampoco es necesario
             Diagrama UML (usando StarUML)                              en Persona hacer un require_once a Persona, ya
                                                                        estás en la misma clase.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
110 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Veamos primero cómo sería el código de index.php sin crear la clase para probar paso a paso toda la
             letra:

             index.php:
             <?php
             require_once        'Persona.php';
             require_once        'Perro.php';
             require_once        'Gato.php';
             require_once        'Escuela.php';

             /* Micaela tiene un perro */
             $persona = new Persona('Micaela', 5);
             $perro = new Perro('Tito', 'blanco y negro');

             $persona->setPerro($perro);

             /* Martina, dueña del mismo perro... */
             $persona1 = new Persona('Martina', 3);
             $persona1->setPerro($perro);

             /* ... y hermana de Micaela */
             $persona->setHermano($persona1);

             /* Marcos es dueño de un gato */
             $persona2 = new Persona('Marcos', 6);
             $persona2->setGato(new Gato());

             /* Escuela Dos Corazones */

             $escuela = new Escuela('Dos Corazones');

             /* ... Micaela va junto con 5 niños más ... */

             $escuela->addAlumno($persona);
             $escuela->addAlumno($persona1);
             $escuela->addAlumno($persona2);
             $escuela->addAlumno(new Persona('Julio',5));
             $escuela->addAlumno(new Persona('Martín',4));
             $escuela->addAlumno(new Persona('Carla',4));




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
111 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



                                                                        Para poder modificar este comportamiento en
             Detalle importante a tener en
                                                                        el contexto de PHP4, habría que hacer cosas
             cuenta con las relaciones                                  como cambiar la función para que retorne el
             PHP4 era un lenguaje donde todo era “por                   objeto modificado y sustituirlo por el que quedó
             valor” y había que especificar explícitamente              fuera (así forzamos a que cambie):
             cuando era “por referencia”. PHP5 se pone a
             tono con los lenguajes POO y de ahora en más
                                                                        $persona = agregar_hermano($persona);
             todos los objetos son siempre “por referencia”,
             por lo que no hay que especificar nada (y en
             ningún otro lenguaje POO).
                                                                        Todo esto cambia cuando usamos por defecto
             ¿Qué significa esto?                                       “pasaje por referencia” (lo que ocurre en
                                                                        PHP5), ya que si pasamos un objeto es la
             Si fuera por valor, cuando hacemos:                        referencia a este y no importa donde estemos,
                                                                        si cambia, estamos cambiando el objeto original
                                                                        (y único).

  $persona = new Persona();
                                                                        Se deberá entender entonces que no es
                                                                        necesario retornar nada cuando modificamos
  agregar_hermano($persona);                                            un objeto dentro de una función.
  var_dump($persona);

  /* Funciones */

  function agregar_hermano($persona){
       $hermano = new Persona();
       $persona->setHermano($hermano);
  }


             El var_dump final no mostraría al hermano, ya
             que cuando se envió por parámetro, pasó por
             valor y lo que cambió fue solo eso, no el objeto
             original, y fuera de la función, no ocurrió nada.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
112 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Por lo tanto, el orden de la asignaciones entre            Repuesta: no es necesario, la persona que
             los objetos no son realmente necesarias si                 mandamos a la escuela es la misma que
             manejamos correctamente el concepto de las                 tenemos luego, ya que es una referencia.
             referencias.                                               Cualquier referencia que modifiquemos, afecta
                                                                        al mismo objeto del sistema.
             Por ejemplo:


        $persona = new Persona();                                       ¿Y ahora, cómo puedo probar el contenido de
                                                                         cada uno implementando correctamente los
        $escuela->addAlumno($persona);
                                                                                  toString() de los objetos?
        $persona->addPerro($perro);




             ¿El perro quedó asociado a la persona que
             entró a la escuela? ¿Si? ¿no?

             ¿Si agregamos a la persona antes de asociarla
             con el perro, no debería primero haber
             agregado al perro y luego mandar a la persona a
             la escuela?




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
113 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             El método público toString()                               toString es un método público, pero que no
                                                                        hace falta ejecutar literalmente, ya que lo hace
             Todas las clases que tengan nombre (Persona,
                                                                        de forma automáticamente con cualquier
             Perro) podrían tener un toString de este tipo:
                                                                        operación que obligue/necesite hacer que un
                                                                        objeto deba comportarse como un String
                                                                        (“cadena de texto”).
        Perro.php:
                                                                        El único caso que podría ser más complejo sería
        <?php
                                                                        el toString de Escuela, que podría ser solo la
        class Perro                                                     impresión del nombre, pero si queremos que
        {                                                               muestre todo su contenido (que no es necesario
           /* … */                                                      hacerlo en el toString, ya que lo anterior es lo
                                                                        justo).
             public function __toString()
             {
                                                                        Ejemplos:
                 return $this->_nombre;
             }
        }                                                               - ¿Si tenemos un objeto Persona, cual sería la
                                                                        mínima información en texto que lo
                                                                        describiría? Generalmente el nombre y
                                                                        apellido.

             Así cuando necesitemos “convertir un Objeto a              - ¿Si tenemos un objeto usuario, cual sería la
             String” (“imprimirlo”), simplemente haremos:               mínima información en texto que lo
                                                                        describiría? Generalmente el nombre de
             echo $perro;                                               usuario.

             Que es lo mismo decir (y funciona):                        - ¿Si estamos hablando de una mascota?
                                                                        Simplemente el nombre.
             echo $perro->__toString();
                                                                        - ¿Si estamos hablando de una pieza de
                                                                        repuesto de un auto? La descripción de la
                                                                        misma.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
114 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Por ejemplo, para la Escuela podría ser:

             <?php
             class Escuela
             {
               private $_nombre;
               private $_alumnos = array();

                 public function __construct($nombre)
                 {
                     $this->_nombre = $nombre;
                 }
                 public function addAlumno(Persona $persona)
                 {
                     $this->_alumnos[] = $persona;
                 }
                 public function __toString()
                 {
                     $retorno = '';

                       foreach ($this->_alumnos as $alumno) {
                           $retorno .= $alumno .' ';
                           /*
                            * Es lo mismo que decir
                            *
                            * $retorno .= $alumno->__toString() .' ';
                            *
                            * solo que el objeto sabe cómo convertirse en
                             * String, tema que detecta cuando se hace
                             * una operación de suma de cadenas
                             * con el punto ".".
                            */
                            }
                            return $retorno;
                        }

                      }
             }




             Aunque de todas formas se sugiere la simplicidad, lo correcto es que la Escuela solo retorne en el
             toString() el nombre de la misma, y que la información sobre los alumnos sea dada por un método
             específico para eso.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
115 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com




             Lo que dice el manual de
                                                                        Para el caso de Micaela, como es una persona,
             toString()                                                 diría que lo más adecuado sería (solo agrego el
                                                                        método nuevo):
             En resumen, toString() (a pesar de lo sintético
             del manual oficial) es:

             “El método reservado "toString()" es la          <?php
             forma que todo lenguaje POO tiene para           class Persona
             que nosotros los desarrolladores podamos         {
                                                                 public function __toString()
             definir cómo convertir un objeto en "texto
                                                                 {
             plano".”                                               return $this->_nombre . '' .$this->_apellido;
                                                                 }
             En Java es muy común solicitar una               }
             colección de objetos de tipo Persona y
             luego tirarle directamente esta información a
             un "combo" (otro objeto de la interfaz), y este            Si fuera un Usuario y no solo una Persona, tal
             sabrá qué información mostrar a partir que                 vez agregaría en el toString el id + nombre +
             cada objeto tiene claramente definido su                   apellido.
             toString().
                                                                        En resumen: acorta el camino, se estandariza
             Si tomamos nuestra clase Persona y hago:                   una acción muy recurrente, y evita que
                                                                        tengamos un getNombre() ó getDefinición() o
             echo $micaela;                                             similar que dependa de nosotros agregarlo.

             ¿Qué hace? ¿Cómo puedo imprimir esto?                      Por todas estas razones todo objeto debería
             ¿Cómo lo traduzco?                                         tener definido siempre su toString().

             El método toString sirve para eso, la regla
             sintáctica es que ese método solo puede
             retornar un String, la regla conceptual dice que
             ese String debe representar con muy poca
             información la esencia del objeto que estoy
             tratando de imprimir.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
116 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Agregando las relaciones que se ven desde Index
             Ahora bien, una vez que tenemos resuelto nuestro sistema, ¿cómo sería el diagrama UML completo con
             las relaciones a todas las clases que está usando?

             Si hiciéramos “ingeniería inversa”, deberíamos traducir en flechas por cada requiere / include de
             nuestro index.php y el diagrama nos quedaría así:




             Index está necesitando conocer a todas las clases para luego relacionarlas entre ellas (hace “new” de las
             clases y luego las relaciona).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
117 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Crear la clase Index a partir de la representación UML
             Lo más importante ver aquí, además que todo el código presentado anteriormente en el index iría en un
             método ejecutar de la clase Index, son cómo todas las flechas se representan de acuerdo al diagrama, y
             así hay que hacerlo para cada una de las clases del diseño (revisar las flechas y representarlas
             exactamente con un require_once).

             <?php
             require_once      'Persona.php';
             require_once      'Perro.php';
             require_once      'Gato.php';
             require_once      'Escuela.php';

             class Index
             {
                public function ejecutar()
                {
                   /* Micaela tiene un perro */
                   $persona = new Persona('Micaela', 5);
                   $perro = new Perro('Tito', 'blanco y negro');
                   $persona->setPerro($perro);

                      /* Martina, dueña del mismo perro... */
                      $persona1 = new Persona('Martina', 3);
                      $persona1->setPerro($perro);

                      /* ... y hermana de Micaela */
                      $persona->setHermano($persona1);

                      /* Marcos es dueño de un gato */
                      $persona2 = new Persona('Marcos', 6);
                      $persona2->setGato(new Gato());

                      /* Escuela Dos Corazones */
                      $escuela = new Escuela('Dos Corazones');

                      /* ... Micaela va junto con 5 niños más ... */
                      $escuela->addAlumno($persona);
                      $escuela->addAlumno($persona1);
                      $escuela->addAlumno($persona2);
                      $escuela->addAlumno(new Persona('Julio',5));
                      $escuela->addAlumno(new Persona('Martín',4));
                      $escuela->addAlumno(new Persona('Carla',4));

                      echo $escuela;
                  }
             }

             Index::ejecutar();


             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
118 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Segunda propuesta de diseño
             Atención con la “sobre-ingeniería”, hay que evaluar si estas mejoras no son demasiadas porque el
             contexto podría no requerirlo.

             Cambios

                    Se cambian las relaciones de asociación por agregación en el caso que decidamos que pueden
                     existir más de un elemento de Perros, Gatos y Hermanos (varios hermanos, varias mascotas,
                     etc).

                    Se agrega una Nota UML, que sirve para agregar explicaciones (puede ser hasta pequeñas
                     porciones de código) para entender cómo traducir a código. Generalmente lo que se tiende a
                     explicar es el “index”, el punto de arranca para ver cómo hacer funcionar todo el sistema (ya
                     que a veces interpretar el diagrama de clases no es tan obvio).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
119 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Diagrama UML




                        Nota

                        Se omite la traducción de UML a PHP por considerar que su
                        implementación a esta altura es simple y haría extremadamente
                        extensas las explicaciones con código que ocupa decenas de páginas,
                        cuando mostrando las principales clases nos enfocamos en lo importante
                        de la solución.

                        De todas formas puedes entrar a http://usuarios.surforce.com y obtener
                        los fuentes completos y explicados de todo el libro.



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
120 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             En Resumen
             Siempre se pueden plantear más de un diseño y esto quedará a discusión del equipo de trabajo y
             ajustándose a un contexto determinado. Aquí se plantean un par de diseños que no necesariamente
             son “la única solución posible” y se busca extender la comprensión de los temas tratados hasta el
             momento.

             Lo fundamental de este ejercicio es comprender:

                    Las distintas relaciones entre clases y su representación en código

                    Reafirmar que los objetos pasan siempre por referencia y no se necesita ser retornados o en
                     determinados casos, ni siquiera un orden específico en sus asignaciones, ya que siempre
                     estamos tratando con una referencia al mismo objeto (no copias).

                    La importancia del “index” como concepto de punto de partida de resolución del problema
                     general.

                    El uso correcto del toString(), más allá de lo sintáctico, cual es el concepto que debemos tener
                     en cuenta a la hora de definirlo.



             ¡Cualquier duda, envía una consulta! ;-)




                  Crees que al capítulo le faltó algo?

                  Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
121 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Capítulo 12 - Ejercicio "La Escuela y los coches escolares"
             En este ejercicio observaremos cómo se van incrementando las relaciones entre las clases y cómo una
             clase se compone de varias otras clases y que las clases externas no necesariamente tienen que
             conocerlas.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
122 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com



             Requerimientos

             "Tenemos una escuela que está ubicada en Ignacio Media 1212 y cuenta con 3 coches escolares
             para transportar a los niños de su casa a la escuela. Cada coche puede llevar como máximo a 5
             niños y tienen un barrio/zona asignada.

             Existe un conductor por coche y un ayudante, y cada vez que un niño sube a la camioneta se le
             pregunta su nombre como forma de control. Para seguridad de la escuela y de los padres, se
             desea poder saber en todo momento el contenido de niños de todas las camionetas, el
             contenido de niños de una camioneta en particular y poder consultar por un niño en particular
             y saber en qué camioneta está"


             Guía

             Empezar a hacer un diagrama UML que represente esta realidad y posteriormente realizar en
             index.php lo que se solicita en la letra que debe hacer el sistema:

                    Saber el contenido de todas las camionetas
                    Saber el contenido de una camioneta
                    Poder buscar a un niño y saber en qué camioneta está
                    Representar como Personas al conductor y al ayudante
                    El diagrama UML no debe tener información de tareas anteriores (no va ni perro, gato,
                     etc)

             Entender que desde index.php es el lugar "donde los padres consultarían esta información" (no
             representar con clases a los padres), por lo tanto desde ahí se debe preguntar a la escuela y
             esta devolver la información, nunca a un coche de forma directa.

             Nota: se debe usar solo lo visto hasta el momento en los capítulos anteriores.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
123 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Solución
             Este ejercicio vuelve a poner foco en el tema                 Dificultad para determinar cuota de
             (fundamental) de las relaciones entre clases y la              responsabilidad de cada uno de los objetos
             importancia de entender al ”objeto” como                       relacionados: cuando diseñamos una clase,
             “unidad de trabajo” sin desarmarlo de forma                    siempre deberíamos pararnos en ella y
             innecesaria.                                                   preguntar “¿Cuál debería ser su
                                                                            responsabilidad? ¿qué no debería hacer y sí
             Excepciones: cómo aún no disponemos de la
                                                                            pedirle a otra clase que haga (porque es
             herencia para estos ejercicios se tomarán como
                                                                            responsabilidad de otra clase)?”. Si hacemos
             válidos diseños con clases específicas más allá
                                                                            un diseño de Escuela con Camionetas que
             de Persona (Niño, Ayudante, Conductor, etc).
                                                                            tienen Pasajeros que a su vez cada uno
              “Errores Habituales”                                          tiene un nombre, la solución directa debería
                                                                            ser:
             La mayoría de los alumnos al llegar a este nivel
             los errores fueron pocos, principalmente por                          o   El “Padre” le pregunta a la
             descuidos, otras por subestimar los                                       Escuela “¿Dónde está mi
             requerimientos (no leerlos con atención) y                                niño?” (pregunta por su
             pensar que los requerimientos solicitados no                              nombre, ya que quiere saber
             podían ser implementados (como buscar el niño                             donde está “la instancia”).
             y saber su coche):
                                                                                   o   La Escuela no lo sabe
                 Existieron diseños que implementaban una                             directamente, tiene que
                  clase Camioneta, pero tenía como                                     preguntarle a todas las
                  atributos camioneta1, camioneta2 y                                   camionetas y hacer la misma
                  camioneta3, lo cual no es correcto. Se                               pregunta que le hicieron los
                  define una clase Camioneta y luego una                               padres: “¿Dónde está el niño
                  instancia para cada una de ellas, a lo sumo,                         X?”
                  contendrá un atributo “alumnos” para
                  almacenar sus pasajeros.                                         o   La camioneta está en similar
                                                                                       situación que la Escuela, solo
                 Confusión en el UML al definir el tipo                               puede recorrer sus pasajeros y
                  cuando debíamos armar las colecciones de                             preguntar uno por uno cómo se
                  objetos: en algunos casos usaban                                     llama hasta que alguno
                  colCoches:Coche, cuando en realidad el tipo                          coincida. Evidentemente el
                  es Array (que sí contendrá dentro coches).                           Pasajero debe poder decir
                                                                                       cómo se llama.

                                                                                   o   Luego, se retorna una
                                                                                       referencia al objeto Niño o al
                                                                                       objeto Camioneta (según sea la
                                                                                       necesidad y nuestro diseño).



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
124 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



                 No diferenciar cuando usar setAlgo(objeto)               Parámetros/métodos/atributos no
                  y addAlgo(objeto): pensar que el primero                  descriptivos o abreviados (UML): he visto
                  caso es cuando asocio un objeto con otro y                casos en donde se documentaba
                  en el segundo caso cuando puedo “agregar”                 buscarPersona(n:String):Persona, donde el
                  varias asociaciones (de una a muchas                      “n” no se entiende con claridad a qué se
                  asociaciones).                                            refiere. No ahorren caracteres, es mejor
                                                                            dejar claro con el nombre del parámetro a
                 Uso de tipo Object y no uno concreto                      qué nos referimos. No siempre es mejor
                  (como ser Persona, Coche, etc): a pesar que               documentar comentando “de más” un
                  en todo lenguaje 100% Orientado a Objetos                 código o un diagrama; si hacemos las cosas
                  “todo objeto hereda de un objeto llamado                  detalladas se entenderán directamente sin
                  Object”, no se aplica en nuestros problemas               “anexos”. Una variable, atributo,
                  no definir el tipo concreto y dejar uno                   parámetro, método bien especificado se
                  genérico de tipo “Object”                                 auto-documenta, no necesita un
                                                                            comentario.
                 Desarmar los objetos, retornar valores y no
                  objetos: en algunos casos he visto que si se             Los fuentes PHP deben evitar el tag de
                  buscaba una persona se retornaba un String                cierre de PHP: el estándar solicita esto, ya
                  que podría ser el nombre del objeto.                      que es casi histórico que PHP requiera
                  Sugerencia, acostúmbrense a mantener el                   apertura y cierre de tag. Se argumenta que
                  criterio que nuestra “unidad” debería ser                 también evita muchos errores de caracteres
                  “un objeto”, por lo tanto retornemos                      ocultos en la última línea. A menos que lo
                  objetos y no los desarmemos. Si buscamos                  necesites para embeber PHP/HTML, no
                  una persona a partir de un nombre que nos                 cierres con el tag ?>
                  pasaron (String), en vez de retornar un                  Las variables del lenguaje null, false, true
                  Boolean (true = encontrado), retornar el                  van siempre en minúsculas: otro error que
                  objeto encontrado o de lo contrario null.                 cometo, ya que se pueden definir tanto en
                                                                            mayúsculas como en minúsculas, y siempre
                                                                            las entendí como “constantes” y estas
                                                                            deben estar en mayúsculas. Esto último no
                                                                            es correcto, deben ir siempre en minúsculas
                                                                            (estándar Zend).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
125 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             “Comentarios Generales”
                    La búsqueda se hacía directamente con el objeto a encontrar: no necesariamente quiere decir
                     que esté mal, pero quiero recalcar todas las alternativas posibles.

                         a.    En la mayoría de los casos se hace desde la escuela un
                              buscarAlumno($alumno):Coche, y justamente el alumno es el que se pasa por
                              parámetro. Se podría hacer una variante más genérica como preguntar por el nombre y
                              retornar la referencia del coche con el niño dentro (una forma de saber en qué coche se
                              encuentra), o en otra variante si simplificamos, una búsqueda por solo el niño (retorna
                              Niño) con solo ingresar su nombre.

                         b. Otra posibilidad crear un “objeto parámetro”, una instancia vacía de Niño y donde los
                            parámetros que se carguen sirvan para hacer la búsqueda del niño. Por ejemplo, crear
                            un niño con solo el nombre asignado, o si quisiéramos, asignaríamos la edad para que la
                            búsqueda la haga por nombre y edad a la vez.

                    Para el Coche Escolar definir una constante en la clase LIMITE_CAPACIDAD = 5: esto es una
                     técnica de refactoring que se llama “eliminar los números mágicos" y ayudar a documentar sin
                     necesidad de agregar comentarios de más (un buen código es el que no necesita comentarios
                     para explicarse).



                     class CocheEscolar
                     {
                        private $_colAlumnos = array();

                         const LIMITE_CAPACIDAD = 5;

                         public function estaLleno()
                         {
                            return count($this->_colAlumnos) >= self::LIMITE_CAPACIDAD;
                         }

                     }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
126 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Navegabilidad
             Navegabilidad se le dice al camino que debemos hacer para obtener la información necesaria a partir
             del diseño de los objetos del problema y sus interacciones. Ya vimos que lo más natural es pensar
             Escuela -> Coche -> Niño, pero existen alternativas y ninguna es menos válida que la otra (más si el
             recorrido entre clases ayuda y no dificulta extraer la información que necesitamos).

             Una alternativa: cambiar la “navegabilidad”

                    La escuela “conoce” a los niños

                    Los niños “conocen” a sus camionetas

             Por lo pronto este diseño permite fácilmente obtener un niño y preguntarle ¿cual es su camioneta?. Si
             no hubiera ninguna flecha que se comunique con las camionetas deberíamos pasar por los niños para
             hacer cualquier cosa que requiera de las camionetas.

             ¿Cual es mejor?

             Depende de la información que estamos buscando que el sistema deba procesar, ya que según el caso
             una ruta nos será más conveniente que la otra y la razón la debemos decidir nosotros.




                               Consejo

                               No debemos tener miedo de optar por una u otra navegabilidad,
                               es completamente normal tener que hacerlo, no existe una única
                               navegación posible y es fundamental ajustarla para obtener el
                               acceso óptimo a las clases. No es sano quedarnos con una
                               navegación que nos parece más “natural” pero que nos complique
                               a la hora de extraer o encontrar los objetos que necesitamos.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
127 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Cómo deberían ser las
             búsquedas                                                   Si estamos hablando de Escuela y Coche, y
                                                                         suponemos que el dato es la matrícula,
                 Debemos mantener el foco en que para un
                                                                         deberíamos hacer:
                 sistema “Orientado a Objetos” la unidad de
                 trabajo son siempre “objetos”, por lo tanto
                 para la búsqueda de un Alumno, si lo                   $cocheEncontrado = $escuela->buscarCoche('123456');
                 encontramos, debemos retornar la instancia
                 del objeto, de lo contrario retornamos                  y dentro del método hacer un foreach que
                 “null” (como estándar de “no encontrado”).              pregunte por ese dato, si lo encuentra, lo
                                                                         retorna.
                 Repasando cómo funciona

                 Si se agrega desde A la clase B,
                 simplemente es:

                  $a->agrego(b);

                 Y si se necesita retornar la clase B desde
                 A, es simplemente

                   $claseB = $a->retornoB();

                 Ya que internamente una vez que se
                 encuentra la clase B del array de la clase A,
                 simplemente se devuelve una referencia
                 con un “return” (el objeto sigue siendo
                 único, pero ahora hay dos referencias al
                 mismo objeto).

                 Si es un coche, deberían preguntar en el
                 método de búsqueda un dato que permita
                 buscar dentro del array, y lo que debemos
                 hacer es preguntar a cada instancia por esa
                 información.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
128 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diagrama UML




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
129 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Resumen
             En este ejercicio podemos observar las relaciones entre las clases y cómo se van componiendo unas
             clases a partir de otras, como también que no es necesario saber o preguntar por un “id” como si fuera
             una base de datos para obtener un objeto de terminado, no existiendo necesidad ya que todos los
             objetos de por sí son únicos, aún si son de la misma clase.




                Desearías que se ampliara este capítulo?

                Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
130 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com



             Capítulo 13 - Ejercicio “Implementar diagrama de diseNo UML”
             Daremos vuelta la dinámica de los ejercicios y ahora recibimos un diagrama UML y debemos
             interpretarlo y codificarlo.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
131 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Requerimientos
             A partir del diseño UML presentado en la solución del ejercicio anterior, traducir "exactamente" a
             código PHP.

                                                     "No subestimar el ejercicio"


             Debemos cuidar al detalle cada traducción de UML a PHP, a esta altura no pueden haber errores.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
132 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Solución
             Aquí vemos que lo que podría ser un ejercicio repetitivo y simple para muchos, gran cantidad de
             alumnos en los cursos a distancia falló en representar correctamente las relaciones (lo más importante)
             y posteriormente traducir sin errores toda la información vertida en el UML.

             Se esperaba

             Que no se creara desde index dependencias si no estaban representadas en el diagrama: como estaba
             planteado el UML, no había relaciones con Ayudante, Conductor y Casa. La idea era tentarlos, pero que
             finalmente resolvieran que crear Ayudante y Conductor solo era un problema de CocheEscolar y que
             Casa era un problema de Niño.

             Aunque incluyendo todas las clases desde Index se tenga “técnicamente” acceso a las mismas (porque
             PHP “suma” todas las clases y las ejecuta como un único fuente) no se ajusta al diseño UML hacer uso de
             esas clases. Por lo tanto, y siguiendo el diagrama de relaciones, Index solo debe tener relación directa
             con las clases que están definidas en las flechas y así el resto de las relaciones (más adelante veremos
             en los casos muy específicos que esta situación podría cambiar).



                       Index solo conoce a “A”, no conoce ni a “B” ni a “C”




                                                             Index -> solo require y usa solo “A”

                                                             “A” -> solo requiere a “B” y usa solo “B”

                                                             “B” -> solo requiere a “C” y usa solo “C”




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
133 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                           www.surforce.com



             ¿Qué sucedería si se están
             usando mal las relaciones?
                                                                        Por lo tanto, para verlo de forma gráfica,
             El diseño es frágil y al reusar las clases en otros        tenemos la siguiente visibilidad
             contextos darán error al no tener el
             require_once correspondiente para poder
             encontrar los fuentes necesarios.

             Por ejemplo, si desde Index usamos la clase “B”
             (que técnicamente su fuente está disponible
             porque lo incluye “A”) y mañana “A” cambia su
             diseño interno y decide no usar más “B” y usar
             de ahora en más “C”, ¿cómo nos afectaría?
                                                                               Desde Index
             Si las relaciones están mal implementadas, en
             este caso los cambios internos de “A” afectarán
             a Index porque conoce directamente a “B” (y lo
             usa), mientras que si se hubiera respetado el
             diseño, Index solo conocería “A” y baja
             enormemente las probabilidades que este
             cambio le afecte directamente.
                                                                                                                Desde “A”
             Aunque la probabilidad existe, esta es menor al
             no conocer sus componentes internos ni
             depender de ellos de forma directa (de todas
             formas, volvemos al punto inicial, quien armó el
             diseño UML especificó las relaciones de esta
             forma con un objetivo específico).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
134 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Comentarios adicionales
                    Se podían hacer variantes para estas clases que no se ven desde Index, crear todo a partir de
                     información que llega a los constructores o agregar métodos set / get para cargarlos (pasando
                     solo datos, no instancias).

                    Cabe acotar que de todas formas, aunque pasemos solo los datos, teóricamente estamos
                     pasando un “objeto desarmado” (por decirlo de alguna forma).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
135 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Errores habituales
                    Lo más importante y lo medular del                    “include” no es lo mismo que
                     ejercicio: a pesar que hagamos un                      “require”: el primero da un warning y
                     “require_once” de todas las clases que                 sigue, el segundo falla y no continúa
                     necesitemos desde el index y todo nos                  (“requerir” es más fuerte, nuestra clase
                     funcione, no quiere decir que esté bien.               no puede continuar si le faltan sus
                     Cada require_once debe respetar las                    partes).
                     flechas, de lo contrario las clases
                     cuando sean reusadas y no estén                       Omitir el Index por index, o usar dos,
                     ejecutando desde el index, no                          index.php e Index.php: tengan en
                     funcionarán por la falta de sus                        cuenta para el último caso que en
                     dependencias/asociaciones. Eso son las                 Linux/Unix funciones, pero en Win son
                     flechas, aunque las inclusiones se                     archivos duplicados y se sustituyen
                     repitan (como Escuela -> Niño, Coche -                 entre sí.
                     >Niño) cada clase debe saber sí o sí de
                     quién depende y eso se representa con
                     un require_once por clase que deba
                     representarse.

                    Una convención que definimos al
                     principio es que por nuestro estándar
                     web es requerido contar con un
                     index.php, y que nosotros lo íbamos a
                     presentar en el UML como una clase,
                     pero que físicamente era el único
                     archivo en minúsculas (para que
                     nuestro navegador lo encuentre).

                    Debemos hacer “require_once” y no
                     “include” o “require” solos: si se
                     requieren dos veces una clase, con
                     “_once” solo trae en el primer intento,
                     en los otros casos da error por repetir la
                     definición de una clase.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
136 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Consejos
                    Para simplificar la creación de múltiples instancias, muchas veces se omite la variable temporal
                     que luego es asignada a otro objeto (esto se ve mucho en Java, ya que ayuda a disminuir un
                     poco el exceso de verborragia y kilómetros de código):

                 Ejemplo

                     $niño15 = new Niño('alfredo beltran','Girasoles 7453');

                     $escuela->addAlumnos($niño15);



                 Simplificación


                     $escuela->addAlumnos( new Niño('alfredo beltran','Girasoles 7453') );




                    Aprendan a usar la conversión de tipos: en vez de hacer esto para convertir a texto:


                     return $this->getMatricula()."";



                     cambiar por

                       return (string)$this->getMatricula();




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
137 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diagrama UML




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
138 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Ejemplo codificado
             index.php
             <?php
             require_once 'CocheEscolar.php';
             require_once 'Nino.php';
             require_once 'Escuela.php';

             abstract class Index
             {
               public function ejecutar()
               {
                 $escuela = new Escuela('Dos Corazones','Ignacio Media 1212');

                     $coche1 = new CocheEscolar('Barrio1','Matricula1','Conductor1','Ayudante1
             ');

                     $coche1->addNiño(new Niño('Micaela', 'Direccion1'));
                     $coche1->addNiño(new Niño('Martina', 'Direccion2'));

                     $niñoEncontrado = $coche1->buscarNiño('Micaela');
                 }
             }

             Index::ejecutar();


             Ejemplo de cómo sería la creación interna de un objeto, sin necesidad que esté creado en el exterior
             para luego recibirlo por parámetros:

             Nino.php:

             <?php                                                      Importante
             require_once 'Casa.php';
                                                                        Prestar especial atención cómo se
             class Niño                                                 corresponde la flecha del diagrama
             {                                                          UML con el require_once de la clase.
               private $_nombre;
               private $_casa;

                 public function __construct($nombre, $direccion)
                 {
                     $this->_nombre = $nombre;
                     $this->_casa = new Casa($direccion);
                 }
                 public function getNombre()
                 {
                     return $this->_nombre;
                 }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
139 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Resumen
             Queda en evidencia que no se pueden subestimar los conocimientos ni la letra de ningún requerimiento.
             A pesar que podría parecer un ejercicio rutinario en los cursos existieron dudas en la mayoría de los
             trabajos.

             Tan importante como hacer los diagramas es aprender a recibirlos e implementarlos. Es muy habitual
             que si trabajamos en una empresa de gran tamaño sea de todos los días trabajar con diagramas
             diseñados por un “Arquitecto de Sistemas”.




               Algún diagrama no se entendió?

               Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
140 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Capítulo 14 - Ejercicio “Sistema para empresa que realiza
             encuestas”
             Un ejercicio más complicado en las relaciones y en la interpretación de los requerimientos.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
141 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Requerimientos
             Una empresa que realiza encuestas necesita implementar un sistema que cumpla con los siguientes
             requerimientos:

                 1.   La empresa registra primero a las personas que van a contestar la encuesta
                 2.   Posteriormente se le asigna una encuesta a la persona; existe una encuesta para cada sexo.
                 3.   La encuesta está compuesta por varias preguntas
                 4.   Se requiere saber en todo momento cuales preguntas fueron respondidas
                 5.   Y si estas fueron correctas o no
                 6.   Finalmente, tener un resumen del resultado de cada encuesta.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
142 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Solución                                                   Requerimientos presentados
             El foco de este ejercicio sigue siendo la
             resolución de las relaciones, pero ahora                   “Una empresa que realiza encuestas necesita
             agregando nuevas dificultades (tratando de                 implementar un sistema que cumpla con los
             acercarnos a la realidad): un contexto más                 siguientes requerimientos:
             confuso (no es resoluble fácilmente y de forma
             tan directa), muchas posibles soluciones y con                1. La empresa registra primero a las
                                                                              personas que van a contestar la
             errores en los requerimientos.
                                                                              encuesta
                                                                           2. Posteriormente se le asigna una
             La pregunta es:
                                                                              encuesta a la persona; existe una
             ¿Cómo lo resolverán? ¿Mantendrán el foco en                      encuesta para cada sexo.
                                                                           3. La encuesta está compuesta por varias
             la simplicidad? ¿En “dividir y conquistarás”?
                                                                              preguntas
             ¿discutirán los requerimientos?                               4. Se requiere saber en todo momento
                                                                              cuales preguntas fueron respondidas
                                                                           5. Y si estas fueron correctas o no
             Posibles dificultades
                                                                        Finalmente, tener un resumen del resultado de
                    Cómo armar las relaciones entre la                 cada encuesta”
                     Empresa y sus componentes
                                                                        Requerimientos Erróneos
                    Qué debe verse desde el exterior (que
                                                                        Primer dificultad, el punto 5 no corresponde
                     lo representa nuestro Index)
                                                                        con el contexto, una encuesta no es un examen,
                    Cómo registrar una encuesta y las                  no tiene preguntas correctas o incorrectas, el
                     respuestas a las preguntas                         sistema solo debe registrar las respuestas para
                                                                        poder analizarlas. También se podría pensar
                    Cómo manejar requerimientos                        que fuera una encuesta “cerrada” donde hay
                     ambiguos y/o erróneos                              múltiples opciones ya definidas (1-5), pero
                                                                        nuevamente, no tenemos una “correcta”.

                                                                        Simplemente un poco de “ruido” ;-)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
143 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com




             Muchos Diseños Posibles

             Un posible problema es tratar de hacer un sistema complejo de primera:

                     “Un sistema complejo que funciona resulta invariablemente de la evolución de un
                     sistema simple que funcionaba. Un sistema complejo diseñado desde cero nunca funciona
                     y no puede ser arreglado para que funcione. Tienes que comenzar de nuevo con un
                     sistema simple que funcione.”

                     – John Gall

             Un enfoque es armar los objetos como elementos independientes (casi olvidándose de su entorno) y
             luego ver de “jugar” con los objetos haciendo que se comuniquen entre ellos (“el objeto A le pide
             información al objeto B, etc.”).

             Por lo tanto, sin importarnos ahora si todo se ve desde Index, el primer planteo podría ser el siguiente:

                 1. Crear las clases con sus atributos a partir de los requerimientos

                 2. Relacionar las clases según lo que necesitamos cumplir de acuerdo con los requerimientos.

                 3. Agregarle los métodos a cada Clase según la responsabilidad que detectamos debería tener cada
                    una y sus relaciones con las demás clases de la solución.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
144 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




             Paso 1 – “Crear las clases y atributos”




             A partir de los requerimientos podemos distinguir todas estas entidades y por lo menos los siguientes
             atributos:

                    “Persona tiene Sexo”

                    La pregunta tiene –por lo menos- que tener un texto.

                    La respuesta tiene –por lo menos- que registrar el texto que responde la Persona.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
145 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com




             Paso 2 – “Relacionar las clases”




                           “La empresa registra primero a las personas que van a contestar la encuesta”




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
146 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com




                   “Posteriormente se le asigna una encuesta a la persona; existe una encuesta para cada sexo”



             La asignación es simplemente una relación entre una persona y una encuesta, que exista una para
             cada sexo en sí no se representaría a través de las relaciones en el diagrama, solo es una regla a tener en
             cuenta (que hay que documentar) a la hora de crear Encuestas. Si tengo 2 encuestas, preguntaré cual es
             el sexo de la persona y le asignaré una u otra. Para este ejercicio no aporta nada implementar esta
             situación.

             También se asume que según los requerimientos, solo hay una encuesta posible por persona, por lo
             tanto no manejamos la posibilidad de tener varias encuestas y crear una “agregación de encuestas”
             desde Persona.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
147 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com




                                         “La encuesta está compuesta por varias preguntas”

             En esta situación podríamos llegar a documentar que las preguntas no tienen sentido de existir si no
             están relacionadas con la encuesta. De todas formas, se pueden dar varios contextos, como por
             ejemplo que la Empresa sea la encargada de crear preguntas y tener un conjunto disponible (“pool de
             preguntas”) para luego seleccionar algunas para una encuesta (con la posibilidad de reusar entre
             encuestas).

             Por ahora no compliquemos el diseño, optemos por una solución más simple (siempre hay tiempo para
             complicarlo).




                            “Se requiere saber en todo momento cuales preguntas fueron respondidas”

             Aquí tal vez es lo más complicado de ver y pueden salir varios diseños posibles para registrar las
             respuestas. Pensemos simple, tenemos una persona, una encuesta y por cada persona tenemos que
             registrar sus respuestas… ¿y si asociamos por cada respuesta a qué pregunta corresponde? (no tenemos
             que preocuparnos a qué encuesta corresponden ya que la Persona ya lo sabe de antemano).



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
148 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             También podemos decir que las respuestas no deberían existir si no existe una asociación con la Persona
             (composición).




             ¿Quién debería crear las Encuestas? ¿La Persona o la Empresa? Tiene más sentido que sea
             responsabilidad de la Empresa conocer a sus encuestas y crearlas.

             ¿Quién debería crear las Preguntas? ¿La Empresa o la propia Encuesta, serán las preguntas un problema
             interno y la Empresa solo pasarle la información para crearlas?

             ¿Index, qué debería conocer?

             En primera instancia haremos que conozca a casi todas las clases sin ningún pudor (dije “casi”, no
             “todas”).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
149 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             “Receta de cocina”                                         5. Por cada Pregunta simulo una respuesta
                                                                           hipotética de una persona, por lo tanto
             Definir Index: ¿qué necesitamos para armar el
                                                                           registro en la Persona qué pregunta
             sistema?
                                                                           estoy respondiendo y mi respuesta
                 1. Creo la Empresa                                        (recordar, la persona ya tiene asociada
                                                                           a qué encuesta corresponde las
                 2. Podemos decidir que crear una                          respuestas y las preguntas, solo
                    encuesta y sus preguntas es                            tendremos una encuesta por persona).
                    completamente problema de la
                    Empresa, por lo tanto cuando se cree la             6. Hacer un resumen de las preguntas que
                    empresa ya existirá una encuesta con                   fueron respondidas, para ello hay que
                    sus preguntas.                                         preguntarle a la persona qué preguntas
                                                                           respondió. Si fueran muchas personas
                 3. Creo a la Persona y le pido una Encuesta               se le puede pedir a la Empresa que
                    a la Empresa y se la asigno a la Persona               recorra a las personas y le pregunte a
                    (para poder ubicar a una encuesta                      cada una lo mismo.
                    determinada se le agrega un atributo
                    “nombre”).

                 4. Posteriormente solicito las preguntas
                    de la encuesta y las recorro




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
150 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             “El código”
             index.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
151 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Empresa.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
152 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




             Encuesta.php




             Pregunta.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
153 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Persona.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
154 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Respuesta.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
155 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Index creado a “prueba y error”
             Si se hicieron todas las relaciones y a “prueba y error” se creó la clase Index y no se sabes cómo definir
             correctamente las relaciones, se puede simplemente buscar todos los “new” y estos representarán
             todas las dependencias de este contexto.

             ¿Qué sucede con las otras clases que uso pero que no creo de forma directa?

             Sí, de alguna forma dependes de ellas, pero de forma “indirecta”, fue la clase responsable de esos
             componentes que nos entregó sus elementos internos.

             Por ejemplo:

                 1. $encuesta = $empresa->getEncuesta($sexo); - La empresa nos entregó un objeto Encuesta,
                    pero en realidad nosotros desde index dependemos de la Empresa. Perfectamente podríamos
                    desarmar el objeto entregado y retornar solo datos, sin conocer los objetos internos (tema
                    sujeto a criterios y discusión).

                 2. $preguntas = $encuesta->getPreguntas(); - Para empeorarla aún más, la encuesta nos entrega
                    un array con objetos de tipo Pregunta. Nuevamente, la relación es indirecta, la encuesta, para
                    facilitar la operación de procesar preguntas nos entregó varios objetos Pregunta.

             Resultado final, Index en este diseño dependería explícitamente de:

             require_once 'Empresa.php';
             require_once 'Persona.php';
             require_once 'Respuesta.php';




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
156 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Finalmente, el diagrama UML de diseño posible para nuestro problema podría verse así (enfocado a las
             relaciones generales de las clases):




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
157 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Como otra opción, un diagrama con absolutamente todos los atributos y métodos, aún si estos se
             interpretan de las relaciones (de todas formas se omiten los toString por considerarlos triviales en este
             caso).




             Perfectamente se podría armar un diseño que desde Index tenga una flecha de dependencia con todas
             las clases del diagrama y crear libremente y de forma directa todo y luego relacionar objetos entre ellos.

             Para este diseño se trató de evitar (dentro de lo posible) que para usar esta solución las “clases clientes”
             deban conocer todos los componentes involucrados (Index en este caso).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
158 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Resumen
             Se deja abierto el tema a criterio y discusión del alumno para determinar en cada caso cual sería la
             mejor solución partiendo de las siguientes reflexiones:

                    Es mejor que las clases conozcan lo menos posible de los componentes de otras clases a las
                     que usa.

                    Tampoco es bueno complicar un diseño por intentar esconder absolutamente todas las clases
                     e intentar que exista una única relación contra una sola clase (por poner un ejemplo), ya que
                     esto dificultaría el trabajo de relacionarlas (es mucho más simple relacionar objetos que tratar
                     datos directamente, de la misma forma, intentar evitar retornar un objeto interno cuando en
                     realidad deberíamos usar siempre “objetos de alto nivel” como unidad).

                    A pesar que enviemos los datos por parámetros y no un objeto ya creado, “conceptualmente”
                     esos datos son “el objeto”.

                    Cada vez que una clase tiene un “new” de otra clase, indudablemente hay una flecha que sale
                     hacia esa clase y tiene que haber un correspondiente “require_once” que represente en el
                     código esta relación. “New” y “require_once” van juntos, siempre.

             “La perfección es enemigo de lo bueno”, no existe un único diseño y no hay solo “bien” o “mal”, todas las
             soluciones dependen del contexto concreto y qué alcance se le busca dar.

             Dudas? Espero tu consulta! ;-)




                Necesitas el fuente completo de los diagramas UML?

                Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
159 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Capítulo 15 - “Herencia, Interfaces y Polimorfismo”
             Luego de haber conocido las relaciones más elementales de la POO (dependencia y asociación) y sus
             variantes (agregación y composición), empezaremos a conocer dos nuevas relaciones: la herencia y las
             interfaces.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
160 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             La herencia es una de las relaciones donde más errores conceptuales se comenten, principalmente
             porque es fácil visualizar el “reuso mecánico de código”, lo que lleva a “heredar por el simple hecho de
             disponer de código”.

             Las “interfaces” son las “grandes desconocidas” en el mundo PHP lo que hace que generalmente los
             programadores directamente no las usen, pero lamentablemente se pierden de una gran herramienta
             que es fundamental para poder implementar buenas soluciones de diseño.

             Finalmente un tema que va anidado a la herencia y las interfaces es el “polimorfismo”, considerado “el
             patrón estratégico más importante de la POO”.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
161 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             La Herencia                                                Metáfora: como en la genética, un padre
                                                                        hereda a su hijo determinadas características
             Definición: “es una relación de parentesco
                                                                        que podrá usar a su favor o en su contra. Todo
             entre dos entidades” (una es padre de la otra,
                                                                        lo que esté en su contra será culpa de nuestro
             una es hija de la otra)
                                                                        diseño, de cómo habremos hecho al padre y de
             Antes de abordar lo “mecánico de la herencia”              cuanta información en exceso dejamos que
             quiero destacar lo resaltado :                             llegue a sus hijos.

                     Parentesco. No puede existir herencia si
                     no existe alguna relación “familiar”
                     entre ambas entidades. Uno de los
                     peores errores que se puede cometer -y
                     que     demuestra     la    falta    de
                     conocimientos en Objetos- es usar el
                     mecanismo de la herencia con el único
                     objetivo de “reusar código” de otra
                     clase.

             A partir de estos errores no hay sistema que
             pueda ser bien implementado si todos heredan
             de clases por el simple hecho de querer usar
             sus funcionalidades.

                “La herencia no se debe aplicar de forma
                mecánica, si no hay una relación literal y
               coherente de padre-hijo, la herencia no es
                               aplicable”

             Ya hemos visto en el documento anterior que a
             través de una relación de dependencia se
             puede hacer uso de funcionalidades de otras
             clases y a través de la asociación construir
             objetos más grandes y complejos, sin necesitar
             siquiera de conocer sus mecanismos internos de
             funcionamiento (en otras palabras, “sin conocer
             su código”).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
162 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             Representación UML
             La representación en UML es una “flecha continua” que va desde la clase “hija” hasta la clase “padre”,
             similar a la relación de “asociación”, pero con la diferencia que termina con una punta en forma de
             triángulo.

                     Nota: entender la diferencia de las flechas: si es punteada (“no continua”) la relación es más
                     débil que una “flecha continua”. Por lo tanto la Herencia es una relación igual de fuerte que la
                     asociación, pero más fuerte que una relación como la “dependencia” (“línea punteada”).

             Un diagrama genérico sería:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
163 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



             Cómo se traduce a código                                   Un ejemplo podría ser que la clase Persona
                                                                        tiene atributos privados nombre y apellido, el
             Se pueden hacer varias lecturas:
                                                                        constructor del Padre donde carga estos datos
                 1. Todos los atributos y métodos se                    es público, de la misma forma que el toString,
                    heredan del Padre al Hijo, pero…                    por consiguiente la clase Hijo podrá construir el
                                                                        objeto, cargarlo con su nombre y apellido y
                 2. Los atributos y métodos que son de                  desplegar sus datos cuando haga un echo de
                    tipo “público” (public) o “protegido”               Hijo, todo, sin acceder directamente a los
                    (protected) son visibles directamente               atributos de Persona (porque son privados)
                    desde el Hijo (en el caso particular de             pero sí pudo hacer uso de ellos a través de
                    “público” son visibles de todos lados,              métodos públicos o protegidos desde la clase
                    incluyendo desde el exterior del                    Hijo y que fueron heredados de su padre.
                    objeto).
                                                                        Por consiguiente, veamos algunos ejemplos
                 3. Los atributos y métodos que son de                  reales: definiremos una clase muy genérica
                    tipo “privado” (private) se heredan del             llamada Persona que usaremos luego para crear
                    padre a su hijo pero no son “visibles” de           distintas clases un poco más concretas y
                    forma directa, solo se podrá hacer a                particulares, que se basarán siempre en esa
                    través de métodos del padre que sean                clase. Aquí hay un claro reuso de código, ya que
                    públicos o protegidos.                              todas aprovecharán lo que ya tiene definido
             Funcionalmente hablando podríamos decir que                Persona, pero también es claro que existe una
             un método público “saludar” del padre que su               relación de parentesco con sus hijos (“no se
             hijo hereda se ejecuta de la misma forma que si            hereda por el simple hecho de necesitar acceder
             el hijo lo hubiera implementado él mismo, solo             al código”).
             que el código se encuentra
             “guardado/almacenado” en el padre.
                                                                        Más información:
             Si hacemos un var_dump de un objeto hijo
             veremos la estructura interna del objeto y                 Manual de PHP, sección Visibilidad
             todos sus atributos y métodos privados, pero si
             intentamos usarlos normalmente no podremos
             visualizarlos, pero siguen estando ahí.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
164 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Caso 1 –Usuario hereda de Persona




             Y traducido a código será:

             class Persona
             {
                 private $_nombre;
                 private $_apellido;
             }

             class Usuario extends Persona
             {
             }


             Presta atención, esta herencia no hace nada más que definir que un usuario es, además de tipo
             “Usuario”, de tipo “Persona”, pero como no hay atributos o métodos “no privados” (public, protected),
             no tiene acceso directo (“no es visible”) a lo que es “privado” en su Padre.

             A pesar que es un “mal padre” (chiste), el usuario es ahora de dos tipos, por consiguiente un “Type
             Hinting” (validación de tipos) que filtre personas aceptará al usuario porque “el Usuario es una Persona”.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
165 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             “El Usuario es una Persona”

             Si la Persona estuviera completa (con constructor y toString), este código funcionaría sin problemas en
             la clase Usuario, ya que heredaría de forma automática el constructor y el toString de su Padre, y usaría
             los atributos privados del Padre que el hijo tiene acceso a través de los métodos públicos o protegidos
             (según el caso).




             Usuario será aceptado sin ningún problema por el “Type Hinting / Validación de Tipo” reconoce al
             usuario como un tipo de Persona, lo cual es válido y permite su ingreso al método “imprime”.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
166 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             Caso 2 –Persona agrega un
             constructor
             En este caso tendremos un método construir
             que es público, por lo tanto podemos usarlo
             desde la clase “hija” de forma automática.

             Hay que prestar especial atención que en PHP
             el constructor del padre no se ejecuta de forma
             automática cuando el hijo define su propio
             constructor, por lo tanto hay que invocar de
             forma explícita el constructor del padre.

             Repasando: si el hijo no define su constructor,
             igual que sucede con el toString, el destructor,
             etc, estos serán heredados de su Padre y sí son
             ejecutados de forma automática.

             Si el usuario define su propio constructor:                Aquí, la clase usuario visualiza el método
                                                                        público de su padre, pero no ve directamente
                                                                         los atributos privados, pero, como ahora
                                                                         “Usuario es una Persona”, aunque no
                                                                         podamos “manipular directamente” los
                                                                         atributos, estos están ahí.


                                                                           Nota

                                                                           Para el ejemplo el constructor de Usuario
                                                                           no aporta nada nuevo, la idea aquí es que
                                                                           agregue posteriormente la inicialización de
                                                                           sus atributos particulares y luego use el
                                                                           constructor del Padre para inicializar los
                                                                           atributos heredados.




                                                                        Bueno, hagamos algo útil, usemos esos
                                                                        atributos que parecen “invisibles” ;-)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
167 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Caso 3 –Persona agrega su toString
             Definamos que Usuario es una Persona y que además de tener todos los datos de ella, se define ahora
             en la clase Padre el método toString

             Persona.php:

             <?php

             class Persona
             {
                private $_nombre;
                private $_apellido;

                  public function __construct($nombre, $apellido)
                  {
                     $this->_nombre = $nombre;
                     $this->_apellido = $apellido;
                  }
                  public function __toString()
                  {
                     return $this->_nombre.” “.$this->_apellido;
                  }
             }


             Usuario.php:
             <?php

             require_once „Persona.php‟;

             class Usuario extends Persona
             {
                public function __construct($nombre, $apellido)
                {
                   parent::__construct($nombre, $apellido);
                }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
168 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             index.php:
             <?php
             /* Forma de uso en index.php */

             /* Solo vamos a requerir la clase que
             vamos a usar, no la clase padre, ese es
             problema de la clase Usuario (recuerden
             las flechas de relaciones, cada clase debe
             saber a quién necesita para funcionar) */

             require_once „Usuario.php‟;

             $usuario = new Usuario(„Enrique‟,‟Place‟);

             echo $usuario;


             ¡Y funciona! ;-)

             La explicación es que, a diferencia que el constructor, el toString se hereda porque es público pero este
             se ejecuta de forma automática, sin necesidad de explicitar como en el anterior caso (constructor).

             Aquí es donde deberíamos entender que el principio de ocultación refuerza los diseños al ocultar y
             cerrar el acceso a detalles internos, pero no por eso nos impide poder aprovechar las implementaciones
             realizadas. Como es este caso, no tenemos acceso a los atributos de forma directa y no podemos
             modificarlos, pero perfectamente podemos asignarles información y usarlos.

             Sigamos modificando este ejemplo.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
169 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Caso 4 – Los usuarios necesitan un id y una fecha de ingreso
             Imaginen lo siguiente, nuestro sistema requiere que los usuarios tengan un id y además una fecha de
             ingreso que será definida de forma automática desde el constructor, por lo tanto también ajustaremos
             la información del toString para que muestre el id de usuario.

             El diseño sería el siguiente:




             La clase Persona sigue igual, lo que cambia es la clase Usuario y se ajusta la invocación desde Index:

             Usuario.php:
             <?php
             require_once 'Persona.php';

             class Usuario extends Persona
             {
                 private $_id;
                 private $_fechaIngreso;

                   public function __construct($id, $nombre, $apellido)
                   {
                     parent::__construct($nombre, $apellido);

                     $this->_id = $id;
                     $this->_fechaIngreso = date('w');
                   }
                   public function __toString()
                   {
                       return $this->_id.' '.parent::__toString();
                   }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
170 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             index.php:
             <?php
             require_once 'Usuario.php';

             $usuario = new Usuario(1, 'Enrique','Place');

             echo $usuario; // salida: “1 Enrique Place


             En la clase Usuario armamos el toString juntando la información de una Persona más lo que agrega de
             específico el Usuario.



             Caso 5 – Los usuarios necesitan un id único “autogenerado”
             Aprovecharemos la situación para explicar los “atributos estáticos” (static), o lo que podríamos traducir
             como “atributos / métodos de Clase”. Estos elementos son de acceso común para todas las instancias
             de la misma clase. Un ejemplo práctico puede ser que la clase sepa autogenerar un id nuevo (que no se
             repita cada vez que se construye un objeto), para ello, la clase tienen que contar el id actual para
             asignarle +1 al próximo usuario.

             El diseño sería el siguiente:




             La clase Persona sigue igual, lo que cambia es la clase Usuario y se agrega un atributo protegido (lo cual
             permitirá que una clase herede de Usuario y acceder directamente al atributo como propio) y se ajusta
             el constructor de la clase para no solicitar más el id.

             Atención: para que funcione el autogenerado de id el atributo ultimoId debe ser “estático”


             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
171 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com




             Usuario.php:
             <?php
             require_once 'Persona.php';

             class Usuario extends Persona
             {
                 private $_id;
                 private $_fechaIngreso;
                 static protected $_ultimoId = 0;

                   public function __construct($nombre, $apellido)
                   {
                     parent::__construct($nombre, $apellido);

                     self::$_ultimoId += 1;

                     $this->_id = self::$_ultimoId;
                     $this->_fechaIngreso = date('w');
                   }
                   public function __toString()
                   {
                       return $this->_id.'-'.parent::__toString();
                   }
             }

             La forma de acceder al atributo estático es usando self::$atributo




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
172 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             index.php:
             <?php
             require_once 'Usuario.php';

             $usuario1 = new Usuario('Enrique','Place');
             $usuario2 = new Usuario('Bruce','Lee');
             $usuario3 = new Usuario('Linus','Torvalds');

             echo $usuario1.‟<br>‟.$usuario2.‟<br>‟.$usuario3;


             Y la salida será

             1-Enrique Place
             2-Bruce Lee                           IMPORTANTE
             3-Linus Torvalds
                                                   Cabe destacar que esto ocurre dentro del mundo
                                                   “stateless” (“estado desconectado”), por consiguiente él o
                                                   los objetos se pierden luego de terminada la ejecución de
                                                   la página, iniciando todo nuevamente (si restaura la
                                                   pantalla volverá a contar desde “1”).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
173 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Explicación sobre la                                       “Visibilidad Protegida”
             visibilidad de los atributos y
                                                                        Siguiendo este paralelismo, un padre puede
             métodos
                                                                        prestar el auto a su hijo de la misma forma que
             Existen tres posibilidades: público, privado y             podría prestarlo a otro familiar, pero no a “todo
             protegido.                                                 el mundo” sin restricciones.

             “Visibilidad Pública”                                      Un punto intermedio entre lo privado y lo
                                                                        público, lo “protegido” son los atributos y
             Se puede considerar como “sin restricciones”, lo
                                                                        métodos que pueden ser accedidos de forma
             que es público todos lo pueden acceder o
                                                                        directa como “propios” por parte de los “hijos”
             modificar.
                                                                        de la clase “padre”. Para las clases que no
              Por regla antigua de la POO, en el 99.99% de              tienen una relación de parentesco su significado
              los casos, ningún atributo debe ser público.              es igual al de privado.

             Para la herencia, todo lo que sea “público” se
             hereda a sus hijos, de igual forma que
             cualquiera que acceda a la clase puede ver sus
             atributos y métodos públicos.                                       Recomendación

             “Visibilidad Privada”                                               No hacer abuso de la visibilidad
                                                                                 protegida,     solo     en      casos
             Aquí me gusta hacer la siguiente metáfora, la                       excepcionales donde se justifique. En
             cual ayuda a clarificar mucho el funcionamiento                     los casos habituales todos los
             de esta “visibilidad” en el contexto de la                          atributos deben ser privados y en
             herencia: un atributo o método privado es                           casos excepcionales a través de
             como “la ropa interior”, es personal, es privada,                   algunos     métodos     getter/setter
             y nadie más tiene acceso directo a ella (me                         permitir de forma restringida cargar
             imagino que nadie presta ni usa prestada ropa                       un valor o consultarlo, de la misma
             interior, aún siendo familiares. Si es así, mis                     forma crear atributos y métodos
             disculpas por estos ejemplos, no me quise                           protegidos, nunca aplicar estas
             meter en la vida personal de nadie ;-) ).                           posibilidades de forma general,
                                                                                 mecánica y sin meditar.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
174 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Caso 6 – Ejemplos varios
             Supongamos que nuestro Usuario genérico siguió creciendo en atributos y métodos. Ahora necesitamos
             definir un administrador, pero decidimos por diseño que no es “un tipo de usuario” ya que las
             operaciones que tiene implementadas no se ajustan a lo que estamos buscando, es un administrador
             que tiene la misma información que cualquier otra persona, pero se le agrega la lista de los sistemas que
             es responsable.

             El diseño sería el siguiente:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
175 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Clase abstracta

             Hay que tener cuidado con la traducción al                 En UML el diseño más robusto sería así:
             castellano del manual de PHP donde dice
             “abstracción de clases”, cuando en realidad es
             “clases abstractas”.

             Técnicamente lo que hacemos definir que la
             clase no puede ser instanciada, por lo que se le
             antepone a “class” la palabra “abstract” y en
             UML se representa con el nombre de la clase en
             cursiva ó agregando un “estereotipo” (texto que
             va arriba del nombre de la clase entre <<>>).

             Conceptualmente lo que estamos diciendo es
             que la clase no puede ser usada directamente y
             que nos servirá de molde para crear otras clases
             que sí serán concretas y candidatas a instanciar.

             Por ejemplo, imaginen que tenemos en nuestro
             equipo un desarrollador novato que se le                   En código se traduce en:
             encomienda hacer unas modificaciones en el
             sistema y en vez de usar la clase Usuario usa              <?php
                                                                        abstract class Persona
             directamente la clase Persona y el sistema                 {
             empieza a fallar ya que requiere que los objetos              /*sigue el código de la clase*/
             sean de tipo Persona, pero las operaciones que             }
             requiere solo están implementadas en la clase
                                                                        Lo cual impide hacer
             Usuario y la clase admin.

                                                                        $persona = new Persona();




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
176 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com



             Herencia Múltiple

             La mayoría de los lenguajes POO no
             implementan la herencia múltiple, no porque                         Aclaración
             les falte, se considera que lo único que aporta
             es más posibilidades de errores en los diseños.                     PHP no implementa Herencia
                                                                                 Múltiple como la gran mayoría de los
             Lo que no se podría hacer es heredar de dos o                       lenguajes POO por considerarse
             más padres (siempre uno solo):                                      inconveniente. Tampoco es un
                                                                                 sustituto hacer uso de las interfaces
                                                                                 (que veremos en este mismo
                                                                                 documento) y argumentar que “se
                                                                                 puede hacer herencia múltiple”, ya
                                                                                 que no es lo mismo y aunque se
                                                                                 pudiera, seguiría siendo no
                                                                                 recomendado su uso.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
177 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



             “Sobre-escritura” de métodos

             Otro elemento del lenguaje es poder sobre
             escribir un método que heredamos de nuestro
             padre. Esto se puede hacer simplemente                     Consejo
             volviendo a definir en la case “hija” un método
             con el mismo nombre.                                       Nuevamente, si heredamos de una
                                                                        clase para luego sobre escribir el
                                                                        método que recibimos significará que
             class Padre
             {                                                          muy probablemente el diseño está
                public function metodo()                                mal (o que necesita ser rediseñado),
                {
                   /* código */                                         ya que carece de sentido heredar
                }                                                       algo para luego modificarlo.
             }
             class Hijo extends Padre
             {
                public function metodo()
                {
                   /* nuevo código */
                }
             }

             Si quisiéramos usar el comportamiento original
             y solo modificar parte en la clase hija,
             deberíamos hacer lo mismo que vimos
             anteriormente en el constructor, invocando
             desde “parent”.

             class Hijo extends Padre
             {
                public function metodo()
                {
                   parent::metodo();
                   /* nuevo código */
                }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
178 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com




             Evitar la herencia y la “sobre-escritura” de métodos

             Qué pasaría si necesitáramos endurecer el diseño y evitar que puedan indiscriminadamente modificar
             nuestros métodos o hasta clases a diestra y siniestra? Deberíamos usar la palabra “final”, la que impide
             la herencia de la clase o la sobre-escritura del método, de acuerdo en donde lo apliquemos.

             Impedir heredar la clase Admin

             final class Admin
             {
             }

             Impedir alterar un método que pueda ser heredado

             class Admin
             {
                final function metodo()
                {
                   /* código */
                }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
179 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             “Generalización” versus
             “Especialización”
                                                                        Imaginemos lo contrario, contamos con dos
             El término es muy usado para definir la                    clases que están al mismo nivel, sin relaciones
             “herencia”. La explicación más simple es que               entre ellas, que son Usuario y Admin, ambas
             cada término es usado para referirse a la misma            clases repiten muchos atributos y métodos
             herencia, pero de acuerdo a la lectura que le              (como nombre y apellido), por lo que decidimos
             queramos dar a la relación o al análisis de                hacer una “generalización” y creamos una clase
             diseño que estemos haciendo.                               Persona haciendo un factoreo de todo lo común
                                                                        entre ambas clases.
             Por ejemplo, imaginemos que solo contamos
             con la clase Persona y descubrimos que
             necesitamos una clase Usuario, podemos decir
             entonces que a partir de Persona hicimos una
             “especialización” al crear la clase Usuario, ya
             que tomamos un comportamiento más genérico
             y lo adecuamos a una clase mucho más
             concreta y aplicable a entornos más
             particulares.



                                                                        En resumen: podemos decir que son dos formas
                                                                        distintas de referirnos a la relación de
                                                                        “herencia”.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
180 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                          www.surforce.com



             Entonces, ¿qué es
             Polimorfismo?                                              Este es el diseño

             En sí la palabra solo refiere a “muchas formas” y
             aplicado a la POO es la capacidad de poder
             tomar varias clases que tiene operaciones
             iguales y poder invocar a cualquier instancia el
             mismo método común.

             Ventajas: Poder hacer un diseño genérico que
             se apliquen a varios objetos que tienen
             operaciones comunes.

             Definamos el siguiente contexto: tenemos una
             clase Impresora que se encarga de recibir
             cualquier cosa y la imprime con un “echo”(a
             futuro podrá ser una impresora).

             <?php
             class Impresora
             {
               public function imprimir($algo)
               {
                   echo $algo;
               }
             }

             $impresora = new Impresora();
             $impresora->imprimir('Hola mundo!);

             Listo, tenemos nuestra clase Impresora. Ahora
             bien, luego de analizar este diseño decidimos
             que deberíamos poder recibir objetos que ellos
             mismos sepan cómo imprimirse, y que la
             impresora se encargue solo de ejecutar la
             acción y ella provee su “echo” (que mañana
             podrá ser una operación a bajo nivel que la
             conecte con una impresora real).

             Entonces, luego de discutir con nuestro equipo
             de desarrollo convenimos que todos los
             objetos que quieran imprimirse deberán tener
             un método “imprime” y que cada uno deberá
             saber qué información debe entregar a la
             impresora.



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
181 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             La implementación
                                                                           Comentario
             index.php
                                                                           Este caso en particular lo llamo
             <?php                                                         “polimorfismo de palabra” o
             require_once 'Impresora.php';
             require_once 'Informe.php';                                   “polimorfismo débil” ya que nada me
             require_once 'Curriculum.php';                                asegura que se respeten las reglas del
                                                                           diseño, es más, las reglas no están
             Impresora::imprimir(new Informe());
             Impresora::imprimir(new Curriculum()                          explícitas por código.
             );

             Impresora.php

                                                                        Veamos a continuación cómo reforzar el diseño.
             <?php
             abstract class Impresora
             {
               public function imprimir($algo)
               {
                   echo $algo->imprime();
               }
             }
             Informe.php

             <?php
             class Informe
             {
               public function imprime()
               {
                   return 'imprimo informe';
               }
             }

             Bien, sin darnos cuenta y casi sin necesidad de
             entenderlo, estamos haciendo uso del
             polimorfismo. Nuestra clase de impresión
             recibe distintos tipos de objetos que comparten
             el mismo nombre común de un método que se
             requiere para que la impresora pueda
             funcionar. En distintas etapas de nuestro
             sistema veremos distintas instancias haciendo
             uso del mismo código de impresión:
             “polimorfismo”, “muchas formas”.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
182 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             “Diseño más robusto”

             Bien, el ejemplo anterior funciona, pero el
                                                                               Aplicamos una “generalización”
             diseño es débil, ya que se puede decir que
                                                                                buscando lo común de ambas clases y
             entre los desarrolladores hay un “compromiso
                                                                                creando una clase “Hoja” que tendría
             de palabra” (muy probablemente no
                                                                                toda la información base para cualquier
             documentado) que toda clase que de ahora en
                                                                                documento que quiera imprimirse. Por
             más quiera imprimirse debe implementar este
                                                                                defecto la hoja sabe imprimirse, y en
             método, o de lo contrario fallará.
                                                                                caso de necesitar modificar el
                                                                                comportamiento, sobre-escribiremos el
             Esto es “débil” ya que no está garantizando
                                                                                método imprime en la clase concreta
             nada y dejando supeditado al desarrollador
                                                                                (Currículum o Informe).
             cumplir con lo que se requiere (que muy
                                                                               Se agrega el tipo “Hoja” en el método
             probablemente en caso de olvidar van a tener
                                                                                imprimir de la clase Impresora, por
             que recurrir al fuente para entender cómo
                                                                                consiguiente no permitirá a ningún
             funciona la clase).
                                                                                objeto que no sea de tipo “Hoja” pasar
                                                                                por allí.
             Entonces, mejoremos el diseño.
                                                                        Bien, esto es el tradicional “polimorfismo por
             En este caso hicimos las siguientes
                                                                        herencia”.
             modificaciones:
                                                                                          Ahora bien, el diseño se nos
                                                                                          complicaría si queremos
                                                                                          poder imprimir cosas que no
                                                                                          necesariamente son Hojas,
                                                                                          como un Libro, una revista,
                                                                                          una etiqueta, etc.

                                                                                          ¿Qué hacemos? ¿Creamos
                                                                                          tantas impresoras como
                                                                                          temas distintos
                                                                                          enfrentemos?


                                                                                          ¿La herencia está
                                                                                          limitada?

                                                                        Lamentablemente aquí es donde más se queda
                                                                        corto el manual oficial de PHP al explicar tan
                                                                        brevemente qué es una interfaz (pero bueno, es
                                                                        un manual técnico y no una guía de
                                                                        programación).

             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
183 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com




             Siguiendo el problema anterior, ahora tenemos varios tipos de elementos que no necesariamente son
             simples “hojas”.

             La pregunta es:

                ¿A nuestra impresora le debe interesar cómo son los elementos y cómo tienen que imprimirse?

                                      ¿o es un problema de cada objeto saber cómo hacerlo?

             Hasta ahora veníamos bien, pero si entendimos todo lo expuesto anteriormente, no podemos modificar
             la herencia para que un “Libro sea hijo de Hoja” (incorrecto), o que la “Impresora ahora controle libros
             y que todo herede de Libro” (incorrecto), o todas las variantes que se nos ocurran… el problema es que
             la herencia no cubre estos casos, la herencia solo se aplica cuando hay parentesco, si no lo hay, no
             sirve…

             … a menos que usemos las interfaces!




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
184 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Las interfaces: “el poder desconocido”
             (bueno, por los programadores PHP ;-))

             Las interfaces son similares a la herencia: la herencia “agrupa” clases que “son lo mismo” (relación de
             parentesco) y la interface “agrupa” clases que “que realizan las mismas operaciones” (pero no
             necesariamente son iguales).

             ¿Como solucionaríamos nuestro problema?

             Lo que une a las clases es que todas quieren poder ser aceptadas por la Impresora y por lo tanto todas
             deben tener su método “imprime”

             El diseño de la solución sería así:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
185 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com




             Implementación


             ImprimibleInterface.php




             Curriculum.php




             Impresora.php




                                                                           Explicación
             index.php
                                                                           Si en index.php intentamos imprimir
                                                                           una clase que no cumpla con la
                                                                           interfaz, dará error la ejecución del
                                                                           imprimir de Impresora, ya que solo
                                                                           puede aceptar objetos que
                                                                           implementen la interfaz Imprimible.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
186 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com




             Cómo funciona
                                                                        Detalles importantes
                 1. Inmediatamente que agregamos el tipo
                    Imprimible en el método de la                              La flecha es similar a herencia, solo que
                    Impresora, cualquier objeto que quiera                      es “punteada” (“discontinua”), en vez
                    pasar por ahí deberá implementar la                         de decir “hereda” debemos decir
                    interface Imprimible.                                       “realiza/implementa/cumple” con la
                 2. Una vez que lo implemente, el                               interfaz.
                    compilador de PHP le dirá que su clase                     Todos los métodos de la interfaz son
                    no tienen el método “imprime” (esto lo                      “firmas”, es decir, solo va el nombre y
                    obliga la interface, usted no la está                       la lista de parámetros, no existe
                    cumpliendo), por lo tanto para que                          implementación, ni siquiera van las
                    pueda ser aceptada tiene que contar                         llaves {}.
                    con ese método.

                                                                        Sobre los diagramas: en el anterior podemos
                                                                        ver que la representación es similar a una clase,
                                                                        solo que no tiene la división donde deberían ir
                                                                        los atributos, solo el nombre y los métodos.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
187 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             Repaso de lo visto hasta el momento




             Detalles a tener en cuenta: en este diagrama se ve la interface como si fuera una clase sin la zona de
             atributos (por que no tiene) y para reforzar la documentación (no haría falta igual, se sobre entiende) le
             agrego un comentario como estereotipo “interface”.

             Dependiendo de la herramienta, el libro, el autor, el docente, la interfaz se puede representar también
             como un círculo, lo cual en lo personal prefiero (si la herramienta me deja o encuentro como) ya que a
             simple vista se detectan fácilmente todas las interfaces.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
188 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com




             Las interfaces son “contratos de implementación”

             Una interface es conceptualmente lo que se dice un “contrato de implementación”, ya que para usar
             un servicio (Impresora) tiene que cumplir un contrato (interfaz) que lo obliga a cumplir una serie de
             requisitos (las firmas de métodos que aparecen en la interfaz).

             De esta forma obtenemos un diseño robusto, ya que nada queda supeditado a la palabra y no depende
             del conocimiento o desconocimiento del código, ya que al solo hacer un “implements” el mismo
             compilador nos va guiando con los métodos que nos faltan cumplir

             Anexo

             Se recomienda leer:

                    Herencia de clases y el "Principio de Liskov" (actualizado 15/10/2007)
                    "Herencia múltiple en PHP5"




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
189 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Resumen

             Hicimos la primer introducción a la Herencia y las Interfaces, las diferencias entre ambas, y cómo se
             aplica el polimorfismo y los distintos tipos que hay. También destacamos que conceptualmente el
             Polimorfismo es un “patrón estratégico” y que las interfaces son “contratos de implementación”.

             ¿Dudas? ¡envíame tu consulta! ;-)




               Necesitas más ejemplos para entender este capítulo?

               Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                              SURFORCE / FORMACIÓN
190 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                         www.surforce.com



             Capítulo 16 - Ejercicio “Clase de Persistencia”

             Ya que estamos en un capítulo bastante avanzado en los conceptos, en esta oportunidad te voy
             a soltar un poco más de la mano para que puedas probarte hasta donde puedes llegar (trata de
             hacer el ejercicio sin mirar la solución)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
191 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com



             Requerimientos

             Se necesita diseñar e implementar una clase de persistencia genérica llamada BaseDeDatos
             que pueda recibir distintos tipos de "Manejadores de Base de Datos" como ser MySQL,
             Postgres, etc, desde su constructor. Para ello deberán hacer uso de las interfaces, creando una
             que se llame ManejadorBaseDeDatosInterface y que tenga en su "contrato de implementación"
             las operaciones más básicas y elementales: conectar, desconectar, traer datos ejecutando una
             consulta SQL, etc.

             Posteriormente y para dividir responsabilidades, necesito que creen una clase SQL que se
             encargue de procesar todos los pedidos SQL en partes, así poder a futuro hacer mayores
             controles.

             Por ejemplo, debería tener métodos como:

                    addCampo
                    addTabla
                    addWhere
                    addOrder
                    etc

             Esta primera versión debe contemplar las operaciones de un SELECT y las condiciones serán por
             defecto "AND".

             Con esta clase lo que haremos es evitar que la clase de persistencia tenga el trabajo de hacer
             estos controles y se lo derivaremos a una clase especializada para esa tarea.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
192 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Cómo deberá ser el contenido de la clase Index en index.php:

             require_once 'BaseDeDatos.php';
             require_once 'MySQL.php';
             require_once 'Sql.php';

             $bd = new BaseDeDatos(new MySQL());

             $sql = new Sql();

             $sql->addTable("usuarios");
             $sql->addWhere("id = 1");
             $sql->addWhere("id = 1");
             $sql->addWhere("nombre = 'enrique' ");

             $usuario = $bd->ejecutar($sql); // esto genera SELECT * FROM usuarios WHERE id = 1 AND
             nombre = 'enrique';

             El resultado es un array asociativo que se obtiene de la consulta a la base de datos.

             Deberán realizar el UML y el código de toda la implementación de Index funcionando (no más
             código que este) y convertido en una clase (el código anterior en un método "run").




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
193 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             Solución
              El objetivo de este ejercicio fue obligar a enfrentar una situación muy cotidiana, como puede ser las
             clases de “persistencia de datos” (estas preguntas se repiten una y otra vez en los foros).

                               Definición

                               Con “Persistencia” nos referimos tanto a guardar como recuperar
                               datos de un medio de almacenamiento permanente, por defecto
                               hablamos de una base de datos, pero perfectamente podría ser un
                               archivo de texto plano u otro medio.



             Hay un frase que dice:

                  "Cualquier problema en computación puede resolverse añadiendo otra capa de abstracción"

             La forma de separar el problema de tener distintos motores de base de datos es, justamente, agregando
             una nueva capa de abstracción y evitar conocer directamente los detalles concretos de una base de
             datos en particular.

             Veamos la evolución, paso a paso…




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
194 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                          www.surforce.com



             Primer escenario: “crear una                               Tercer escenario: “abstraer
             conexión a la base de datos”                               el tipo de base de datos”
             Lo primero que implementamos si necesitamos                Imaginen que nuestro producto crece y lo
             persistir nuestros datos en una base de datos              empezamos a comercializar para muchas
             son las funciones de conexión de un motor de               plataformas, y que uno de nuestros nuevos
             base de datos como MySQL. Entonces,                        requerimientos es poder contemplar varios
             buscamos cada una de las sentencias en el                  motores de bases de datos. Para ello tenemos
             manual y en el peor de los casos nuestro código            que “contener el foco de cambio”(*) y adaptar
             se plaga de sentencias tan específicas como:               a nuestro sistema para que solo agregando
             mysql_connect, mysql_query, etc.                           “código nuevo sin modificar lo existente” pueda
                                                                        así soportar más motores de bases como
             Lo que podría suceder luego es que si                      Oracle, MSSQL Server, Informix, Sybase,
             quisiéramos cambiar de motor de base de                    Firebird, etc, etc.
             datos, tendríamos que modificar todas las
             sentencias de nuestro sistema, con el costo que            Por lo tanto, lo que aplicaremos a continuación
             esto tiene.                                                es un principio de diseño que se llama “Abierto
                                                                        / Cerrado” y utiliza el polimorfismo a través de
             Segundo escenario: “crear                                  herencia o de interfaces.
             una clase de persistencia”
             Tratando de prever esta situación podríamos
             crear una “nueva capa de abstracción” y
             generar un clase genéricas (conectar, traer                   Definición
             datos, desconectar) que nos permita                           (*)Foco de cambio: se le dice al lugar
             “esconder” el código específico de MySQL. En                  o lugares de nuestro sistema que por
             caso de necesitar alguna funcionalidad extra o                los requerimientos que estamos
             cambiar de motor, simplemente el impacto en                   desarrollando, es seguro que ahí
             nuestro sistema estaría reducido a modificar                  habrán cambios (agregar, modificar,
             nuestras funcionalidades de una clase que                     etc) por consiguiente debemos
             oculta los detalles de implementación.                        preverlo de alguna forma para bajar
             De todas formas, aún seguiríamos dependiendo                  su costo de modificación /
             de tener una implementación para una u otra                   mantenimiento.
             base de forma exclusiva.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
195 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diseño UML




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
196 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



             Ejemplo codificado
             index.php

             <?php
             require_once 'BaseDeDatos.php';
             require_once 'MySQL.php';
             require_once 'Sql.php';

             abstract class Index
             {
                 public function run()
                 {
                     $bd = new BaseDeDatos(new MySQL());

                         $sql = new Sql();

                         $sql->addTable('usuarios');
                         $sql->addWhere('id = 1');
                         $sql->addWhere('id = 1');
                         $sql->addWhere("nombre = 'enrique' ");

                         $usuario = $bd->ejecutar($sql);

                         echo highlight_string(var_export($usuario, true));

                   }
             }

             Index::run();




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                    SURFORCE / FORMACIÓN
197 de 294           Edición: Julio 2009 / Usuario: Juan Zapata                          www.surforce.com



             ManejadorBaseDeDatosInterface.php

             <?php
             interface ManejadorBaseDeDatosInterface
             {
               public function conectar();
               public function desconectar();
               public function traerDatos(Sql $sql);
             }

             BaseDeDatos.php

             <?php
             require_once 'ManejadorBaseDeDatosInterface.php';
             require_once 'Sql.php';

             class BaseDeDatos
             {
               private $_manejador;

                 public function __construct(ManejadorBaseDeDatosInterface $manejador)
                 {
                     $this->_manejador = $manejador;
                 }
                 public function ejecutar(Sql $sql)
                 {
                     $this->_manejador->conectar();

                        $datos = $this->_manejador->traerDatos($sql);

                        $this->_manejador->desconectar();

                        return $datos;
                 }

             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
198 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



             MySQL.php
             <?php
             require_once 'ManejadorBaseDeDatosInterface.php';

             class MySQL implements ManejadorBaseDeDatosInterface
             {
                 const USUARIO = 'root';
                 const CLAVE = '';
                 const BASE = 'tarea5';
                 const SERVIDOR = 'localhost';

                   private $_conexion;

                   public function conectar()
                   {
                       $this->_conexion = mysql_connect(
                           self::SERVIDOR,
                           self::USUARIO,
                           self::CLAVE
                       );

                        mysql_select_db(
                            self::BASE,
                            $this->_conexion
                        );
                   }
                   public function desconectar()
                   {
                       mysql_close($this->_conexion);
                   }
                   public function traerDatos(Sql $sql)
                   {
                       $resultado = mysql_query($sql, $this->_conexion);

                        while ($fila = mysql_fetch_array($resultado, MYSQL_ASSOC)){
                            $todo[] = $fila;
                        }
                        return $todo;
                   }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
199 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



             Sql.php

             <?php
             class Sql
             {
               private $_colWhere = array();
               private $_colSelect = array('*');
               private $_colFrom = array();

                 public function addTable($table)
                 {
                     $this->_colFrom[] = $table;
                 }
                 public function addWhere($where)
                 {
                     $this->_colWhere[] = $where;
                 }
                 private function _generar()
                 {
                     $select = implode(',',array_unique($this->_colSelect));
                     $from   = implode(',',array_unique($this->_colFrom));
                     $where = implode(' AND ',array_unique($this->_colWhere));

                       return 'SELECT '.$select.' FROM '.$from.' WHERE '.$where;
                 }
                 public function __toString()
                 {
                     return $this->_generar();
                 }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
200 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Principio de diseño “Abierto                               Imaginar que las clases MySQL y Postgres están
             / Cerrado”                                                 “colgadas” desde sus flechas en un punto de
                                                                        apoyo como es la Interface, para agregar una
                                                                        nueva funcionalidad simplemente debemos
             Enunciado formal:                                          agregar nuevas clases “colgadas de la interfaz”
                                                                        –por ejemplo- creando una nueva clase para el
                 "Entidades de Software (clases, módulos,               nuevo motor de base de datos, implementamos
               funciones, etc) deberían ser abiertas para la            la interfaz y esta nos obligará a crear todos los
                extensión y cerradas para la modificación"              métodos necesarios para que la clase genérica
                                                                        BaseDeDatos nos acepte y ejecute.
             Lo cual significa que nuestro costo en el
             desarrollo se da cuando diseñamos un sistema
             que cuando hay cambios de requerimientos
             debemos modificar constantemente, por lo                            Comentario
             tanto un buen diseño deberá ser “Abierto /
             Cerrado”, se diseñará una vez y cuando se                           Se dice que todo buen diseño (como
             necesite agregar nueva funcionalidad se hará                        las implementaciones de los
             sin modificar el código existente, solo                             Patrones de Diseño) de alguna forma
             agregando código nuevo.                                             u otra termina cumpliendo con este
                                                                                 principio.
             ¿Donde está el principio aplicado?

             En la siguientes “flechas”:

                                                                                         Pasando en limpio: cada vez
                                                                                         que necesitemos soportar otro
                                                                                         motor de base de datos
                                                                                         crearemos una nueva clase,
                                                                                         requerimos la interfaz
                                                                                         (“contrato de
                                                                                         implementación”) y esta nos
                                                                                         obligará a implementar los
                                                                                         métodos requeridos para que
                                                                                         todo funcione de acuerdo al
                                                                                         diseño.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
201 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Resumen
             En mundos más “arquitectónicos” como es Java, donde no es nada raro aplicar patrones de diseño, el
             uso de las interfaces es algo habitual y necesario. Cuando diseñan una solución, generalmente crean una
             clase que ofrece un “servicio” y a su vez una “interfaz” que deberán cumplir todas las clases que quieran
             utilizar ese servicio, aplicando de esta forma el principio de diseño “Abierto/Cerrado”.

             Recuerda: trata de mecanizar esta buena práctica, una clase que ofrece un servicio debe implementar
             en conjunto una interfaz que servirá de guía para todas las clases que quieran usar ese servicio.

             Repítelo como un monje budista.




                Tienes una pequeña duda? No hay dudas pequeñas…

                Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
202 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Capítulo 17 - Ejercicio “Librería y la búsqueda de Libros”

             Con el objetivo de reafirmar un tema tan importante como las interfaces, se solicita
             implementar y resolver un nuevo problema: la búsqueda de libros por distintos filtros que no
             conocemos en su totalidad y que irán aumentando con el tiempo.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
203 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Requerimientos

             “Tengo una librería y estoy implementando un sistema para registrar libros. Actualmente mi
             principal problema es la búsqueda de los libros, ya que sé que luego de implementado mi
             sistema de búsquedas me pedirán agregar nuevos filtros de información (he detectado el "foco
             de cambio"), por lo tanto deberé contemplar en el diseño este problema.”

             El diseño borrador es el siguiente:




                                                                        Tener muy en cuenta las relaciones
             El diseño debe poder soportar las siguientes               presentadas en los diagramas:
             búsquedas:
                                                                           Index no ve directamente a los libros
                    Todos los libros de un año: 2008                      Index no ve directamente a los
                    Todos los libros del autor llamado                     Autores
                     "Enrique Place"
                    Todos los libros del tema "PHP"
                    Todos los libros que tengan en su
                     título la palabra "Java" (deberán
                     buscar la coincidencia parcial).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
204 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Solución
             El objetivo de este ejercicio es completar el entendimiento de cómo funcionan las interfaces, cómo se
             aplica el principio de diseño “Abierto / Cerrado” y cómo se pueden implementar las relaciones en
             situaciones donde el acoplamiento es alto entre las clases de la solución.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
205 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diseño “Borrador” (con partes incompletas)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
206 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Diseño “Final” cumpliendo con todos los requerimientos




             Agregados

                    Se agrega la firma del método en la interfaz CriterioFiltro

                    Los nombres de las clases Filtro y sus atributos

                    Se obvian todos los get, set, constructores y toString del diagrama ya que se considera que el
                     lector objetivo es un desarrollador que sabe determinar cuándo necesitarlos implementar (para
                     este diagrama no aportan detalles relevantes).

                    Se agrega en Libro un método getAutores para poder obtener luego su lista de autores.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
207 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com



       index.php:
       <?php
       require_once 'Libreria.php';

       require_once       'FiltroAnual.php';
       require_once       'FiltroAutor.php';
       require_once       'FiltroTema.php';
       require_once       'FiltroTitulo.php';

       abstract class Index
       {
           public function run()
           {
               $libreria = new Libreria();

                   /*
                    * Carga de libros
                    */
                   $libreria->addLibro('Introduccion               a    Java','Java',2007);
                   $libreria->addLibro('Introduccion               a    PHP','PHP',2008);
                   $libreria->addLibro('Introduccion               a    los Patrones de Diseño','Patrones',2007);
                   $libreria->addLibro('Introduccion               a    Zend Framework','Zend',2008);

                   /*
                    * Carga de autores
                    */
                   $libreria->addAutorLibro('Introduccion a PHP', 'Enrique', 'Place');

                   /*
                    * Búsqueda de libros
                    */
                   $libros2008   = $libreria->busqueda(new                  FiltroAnual(2008));
                   $librosAutor = $libreria->busqueda(new                   FiltroAutor('Enrique','Place'));
                   $librosTema   = $libreria->busqueda(new                  FiltroTema('PHP'));
                   $librosTitulo = $libreria->busqueda(new                  FiltroTitulo('Java'));

                   echo   self::_librosEncontrados2Html("Libros                del   2008: ",$libros2008);
                   echo   self::_librosEncontrados2Html("Libros                del   Autor: ",$librosAutor);
                   echo   self::_librosEncontrados2Html("Libros                del   Tema: ",$librosTema);
                   echo   self::_librosEncontrados2Html("Libros                del   Titulo: ",$librosTitulo);
             }
             private function _librosEncontrados2Html($titulo, $array)
             {
                 return $titulo.': ' . implode(', ', $array).'<br><br>';
             }
       }

       Index::run();




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
208 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Comentarios sobre el diseño

                    Se requieren exactamente las clases que dice el diseño UML, ni más ni menos.
                    Se cargan libros y autores sin acceder desde Index a las clases Libro y Autor, todo a través de la
                     clase Librería.

                    Este diseño permite tener un solo diseño de búsqueda y poder intercambiar fácilmente los
                     algoritmos de los criterios de búsqueda.
                    El principio Abierto / Cerrado nos dice que un buen diseño es “cerrado al cambio y abierto a la
                     extensión”, en este caso el “foco de cambio” será agregar nuevos criterios de búsqueda, tema
                     que está resuelto “agregando solo código nuevo” (sin modificar código existente) permite
                     incorporar nueva funcionalidad (esto no es menor si entendemos que tocar algo que funciona
                     puede generar a su vez nuevos bugs o nuevos cambios en cadena). Aquí logramos bajar el costo
                     de mantenimiento de esta parte del sistema.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
209 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Libreria.php:

             <?php
             require_once 'Libro.php';
             require_once 'CriterioFiltro.php';

             class Libreria
             {
                 private $_colLibros = array();

                   public function busqueda(CriterioFiltro $filtro)
                   {
                       $librosRetorno = array();

                             foreach( $this->_colLibros as $libro){
                                 if( $filtro->esSeleccionable($libro)){
                                     $librosRetorno[]= $libro;
                                 }
                             }
                             return $librosRetorno;
                   }
                   public function addLibro($titulo, $tema, $año)
                   {
                     $this->_colLibros[] = new Libro($titulo,$tema,$año);
                   }
                   public function addAutorLibro($titulo, $nombreAutor, $apellidoAutor)
                   {
                       foreach($this->_colLibros as $libro){
                           if($libro->getTitulo() == $titulo){
                             $libro->addAutor($nombreAutor,$apellidoAutor);
                           }
                       }
                   }
             }


             Comentarios

                       La clase Librería sólo requiere Libro, no requiere directamente la clase Autor

                       La búsqueda se realiza recibiendo un criterio y este criterio va recibiendo cada uno de los
                        ítems de la colección de libros, cada vez que el libro coincida con el criterio de filtro este
                        método retornará “true”, por lo tanto lo guardaré en un array para luego devolver a todos los
                        objetos Libros encontrados. El filtro sólo tiene una responsabilidad, confirmar si se cumple el
                        criterio o no.

                       Para agregar un autor de un libro se hace una búsqueda y posteriormente se le da todos los
                        datos al libro para que guarde su autor, todo sin tener que crear una instancia a este nivel.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
210 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Libro.php:
             <?php
             require 'Autor.php';

             class Libro
             {
                 private       $_titulo;
                 private       $_tema;
                 private       $_año;
                 private       $_colAutores = array();

                      public function __construct($titulo,$tema,$año)
                      {
                          $this->_titulo = $titulo;
                          $this->_tema = $tema;
                          $this->_año = $año;
                      }
                      public function addAutor($nombre,$apellido)
                      {
                          $this->_colAutores[] = new Autor($nombre,$apellido);
                      }
                      public function getTitulo()
                      {
                          return $this->_titulo;
                      }
                      public function getTema()
                      {
                          return $this->_tema;
                      }
                      public function getAño()
                      {
                          return $this->_año;
                      }
                      public function getAutores()
                      {
                          return $this->_colAutores;
                      }
                      public function __toString()
                      {
                          return $this->_titulo;
                      }
             }


             Comentarios

                      El Libro sólo conoce al Autor

                      En el UML se obvian todos los get y toString por considerarlos triviales a la hora de abordar el
                       problema real.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
211 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com



             Autor.php:
             <?php
             class Autor
             {
                 private $_nombre;
                 private $_apellido;

                      public function __construct($nombre, $apellido)
                      {
                          $this->_nombre = $nombre;
                          $this->_apellido = $apellido;
                      }
                      public function getNombre()
                      {
                          return $this->_nombre;
                      }
                      public function getApellido()
                      {
                          return $this->_apellido;
                      }
                      public function __toString()
                      {
                          return $this->_nombre . ' ' . $this->_apellido;
                      }
             }


             Comentarios

                      Esta clase no aporta nada nuevo




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
212 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             CriterioFiltro.php:
             <?php
             interface CriterioFiltro
             {
                 public function esSeleccionable(Libro $libro);
             }


             Comentarios

                         No aporta nada nuevo de lo visto a la fecha.



             FiltroAutor.php:
             <?php
             require_once 'CriterioFiltro.php';

             class FiltroAutor implements CriterioFiltro
             {
                 private $_nombre;
                 private $_apellido;

                      public function __construct($nombre,$apellido)
                      {
                          $this->_nombre = $nombre;
                          $this->_apellido = $apellido;
                      }
                      public function esSeleccionable(Libro $libro)
                      {
                          $encontrado = false;

                            foreach($libro->getAutores() as $autor){
                                if($autor->getNombre() == $this->_nombre &&
                                    $autor->getApellido() == $this->_apellido){

                                       $encontrado = true;
                                  }
                            }
                            return $encontrado;
                      }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
213 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



             Comentarios

                    A este nivel sólo conozco a la interfaz

                    esSeleccionable recorre una lista de los autores de un libro para ver si al final coincide con lo
                     solicitado.

                    Cambia la forma de requerir las clases (sujeto a discusión y definición de criterios): podríamos
                     decir que el filtro depende del libro para poder trabajar y no estaría mal implementarlo, pero
                     para este diseño se toma como criterio que las clases de filtro están “altamente acopladas” a
                     los componentes de la clase Librería y por lo tanto no van a trabajar sin ella: sin depender de
                     nada más, sólo de los componentes asociados a la Librería, sin relación directa con Libro (usará
                     el require_once de Libro existente desde Librería).

                    Se crea una “dependencia indirecta” entre el filtro de autor y el autor propiamente dicho: se
                     vuelve a repetir el caso donde el objeto (libro) expone sus componentes internos. El filtro sólo
                     depende del Libro pero este es requerido en la Librería, y a través del require_once de Autor en
                     Libro se accede al mismo. La pregunta que siempre debemos hacer es: ¿qué forma es más
                     conveniente? ¿permitir exponer componentes internos de una clase a favor de simplificar su
                     uso? ó ¿esconder todos los detalles internos para no violar el “Principio de Ocultación” y que los
                     elementos externos no dependan de los elementos internos de las clases con las cuales se
                     relacionan? (efectos en cadena).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
214 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Resumen
             Cuando vi por primera vez en la universidad materias como Diseño Orientado a Objetos y Patrones de
             Diseño (todo bajo Java), este fue particularmente uno de los ejercicios que más “abrió mi mente” y me
             hizo terminar de descubrir lo importante que son los diseños, las relaciones, los diagramas y
             fundamentalmente, que gran herramienta son las interfaces.

             No es raro ver en Java que para hacer o usar tal o cual funcionalidad de una clase hay que implementar
             primero una interfaz para llegar hasta la clase que ofrece la funcionalidad que necesitamos.

             Al principio no será natural esta forma de trabajo ya que poco estamos acostumbrados en el mundo
             PHP a hacerlo de esta forma, pero con el tiempo y la práctica tenemos que mecanizarnos que cada vez
             que necesitemos implementar un servicio deberemos hacer en conjunto una interfaz que guíe cómo
             se debe usar y qué requisitos se deben cumplir.

             Repite como un monje budista:

                    “Un servicio (clase) debe disponer de una interfaz que obligue a cumplir con un contrato de
                                                         implementación”.




                Alguna parte quedó confusa?

                Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                           SURFORCE / FORMACIÓN
215 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                     www.surforce.com



             Capítulo 18 - “Los Paquetes en UML”

             Los paquetes son la representación de un agrupador de clases (o de otros paquetes) en un
             sistema Orientado a Objetos, lo que generalmente se traduce físicamente en un directorio
             (aunque dependiendo de la tecnología esto puede ser más “lógico” que “físico”). Esto nos
             permitirá organizar nuestro sistema y tener un nivel mayor de abstracción




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
216 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Cómo se representan
             En UML se hace gráficamente con el dibujo                  La clase Index se encuentra en la raíz de
             de una "carpeta" como representación del                   nuestro proyecto, y la relación siempre con
             concepto de "agrupador de clases". Este                    y entre los paquetes es de "dependencia".
             gráfico se traduce simplemente en un                       Aquí tenemos un nuevo nivel de abstracción
             subdirectorio físico en nuestra aplicación, y              donde "conocemos" que nuestra clase
             en el caso particular de PHP, cuando una                   Index depende de un paquete "Lógica" (que
             clase de un paquete deba apuntar a una                     a dentro contendrá clases) y que a su vez el
             clase en otro paquete, tendremos una                       paquete de Lógica depende del paquete de
             referencia con un require_once con la ruta                 "Dispositivos".
             directorio/Clase.php.
                                                                        Depender de un paquete no significa otra
                                                                        cosa que "depender concretamente de una
             Según este diagrama:
                                                                        clase del interior del paquete" pero para la
                                                                        representación, nosotros dependemos del
                                                                        "paquete que la contiene".

                                                                        Por ejemplo, es como decir que "el
                                                                        mecánico trabaja sobre el motor
                                                                        (paquete)" y no tener que dar la lista de
                                                                        todos los componentes del motor, o tener
                                                                        que decir que está trabajando
                                                                        concretamente sobre alguna parte en
                                                                        particular del motor (en este contexto no
                                                                        nos interesa tener tanto detalle, estamos
                                                                        abstrayendo complejidad para que sea más
                                                                        fácil de manejar nuestro sistema).

                                                                        Podríamos diseñar un sistema que tenga
                                                                        los paquetes de Ventas, Stock y
                                                                        Contabilidad donde cada uno tendrá una
                                                                        lista extensa de clases pero que en algún
                                                                        momento nos interesará manejarlo a un
                                                                        nivel mucho más abstracto como el
                                                                        "paquete".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
217 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             ¿Qué es una Arquitectura de 3 capas?
             No es más que crear 3 paquetes con nombres como: presentación, dominio y persistencia, y darle a
             cada uno una responsabilidad concreta. La regla será que siempre deberán entrar las peticiones desde
             la interfaz (lo que usa el usuario), pasar por el dominio (donde realmente se resuelve el sistema) y
             finalmente la capa de persistencia (donde se guardan o recuperan los datos).

             Cada capa recibe una petición de la otra, si alguna no tiene nada que hacer con ella, simplemente juega
             de "pasamanos" para la capa correspondiente según su responsabilidad.

             El diagrama tradicional para una arquitectura de 3 capas:




             Nota: veremos luego cómo se aplica en el último ejercició práctico de este libro.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
218 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             ¿Que son entonces los
             Namespaces?
                                                                        PHP5.3 incorporará, a pesar de haber seguido
             Por muchos años los desarrolladores que                    siempre a Java, por primera vez el concepto
             conocemos de otros lenguajes notamos en PHP                de "namespaces". Será la primera versión y aún
             la ausencia del soporte por parte del lenguaje al          no está claro la forma de usarlo (a la fecha
             manejo de "paquetes" a nivel conceptual                    siguen habiendo discusiones sobre "lo mal qu
             (inicialmente lo diagramamos en UML pero en                ese está implementando" esta funcionalidad).
             algún momento debemos codificarlo).                        Por lo pronto es como si no contáramos con ella
                                                                        y debiéramos esperar hasta PHP6.
             Tanto Java como .Net permiten codificar
             claramente un "Paquete UML":                               Para más información sobre este interesante
                                                                        tema, se recomienda leer
                    Java tiene la sentencia "import" que
                     permite definir el paquete en el cual                 PHP5: Diseño en 3 capas y problemas con
                     pertenece la clase en cuestión y a su vez
                     incluir él o los paquetes que                          subdirectorios
                     necesitamos acceder desde una clase
                                                                           "Petición para soporte de Name Spaces en
                     particular.
                    En .Net, por ejemplo con Visual Basic,                 PHP5"
                     el nombre cambia a "namespace" y a
                     pesar que sirve para implementar los                  http://ar2.php.net/manual/es/language.na
                     "paquetes", es un concepto un poco                     mespaces.php
                     más amplio : permite definir que una
                     clase es parte de un paquete,
                     independientemente de donde se
                     encuentre físicamente el archivo de la
                     clase, por lo que podríamos tener varios
                     archivos distribuidos en un sistema pero
                     ser parte del mismo "paquete".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
219 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             En Resumen
             Los paquetes permiten un nuevo nivel de abstracción y que podemos usar para definir una
             arquitectura dividida en 3 capas, que no es más complejo que separar físicamente los archivos de las
             clases bajo el criterio único de la responsabildad de la capa. También vimos que esto puede cambiar con
             un concepto un poco más amplio como son los Namespaces, pero que a los efectos ambos sirven para
             representar los "paquetes".

             Al final de cuentas es un mecanismo más que sirve para estructurar nuestro sistema en elementos de
             más alto nivel y luego relacionarlos entre ellos.




                  Este capítulo te pareció muy breve? Solicita ampliarlo

                  Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
220 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Capítulo 19 - Ejercicio “Programación ‘Orientada a la
             Implementación’ vs ‘Orientada a la Interface’"

             Penúltimo ejercicio y terminamos cerrando con un concepto que considero fundamental,
             además del tema de las interfaces, entender la diferencia entre la programación "orientada a la
             implementación" versus programación "orientada a la interface".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
221 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



             En Abril de 2006 escribí un artículo que cubre el 50 % del tema donde explico lo que es la
             programación orientada a la interfaz y dejo la promesa de terminarlo algún día. Ese día llegó y
             lo haremos juntos cómo la penúltimo ejercicio de este libro.

             Tomando el artículo de referencia (actualizado al día de hoy):

             Programación: "Orientada a la Implementación" versus "Orientada a la Interface" - Parte 1

             Index usa la clase MaquinaDeEscribir.php que se encuentra dentro del paquete"logica", por
             consiguiente, desde la vista de paquetes, Index depende del paquete "logica", y como dentro
             de lógica la clase MaquinaDeEscribir depende de dos clases que están dentro del paquete
             "dispositivos", el paquete "logica" (donde está MaquinaDeEscribir), depende del paquete
             "dispositivos".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
222 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Requerimientos

             Enunciado:"La máquina de escribir tiene un dispositivo de entrada de datos (teclado) y un
             dispositivo de salida de datos (impresora)"

             Como convención los nombres de paquetes son siempre en minúsculas y se traducen como un
             subdirectorio en nuestro sistema como forma de organizar nuestras clases.

             Veamos entonces qué hay dentro de cada paquete. Para este caso se agrega como
             "estereotipo" de cada clase el nombre del paquete al cual pertenecen:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
223 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Lo que solicita el ejercicio es:

                 1. Dos implementaciones que deberán llamarse version1 y version2
                 2. La primera tendrá la programación "orientada a la implementación", deberán
                    completar el diagrama presentado y hacer su implementación.
                 3. La segunda deberá ser programación "orientada a la interfaz" (como dice su nombre,
                    usando "interfaces"), también deberán hacer el diagrama e implementación de la
                    solución (todo de acuerdo a los conceptos vertidos en el artículo presentado
                    oportunamente en el blog):
                 4. Deberá depender de las interfaces y no de las clases concretas.
                 5. Finalmente, cuando el diseño esté completamente terminado, ver la forma de
                    solucionar un problema en el diseño: cambiar la dependencia entre los paquetes, ya
                    que la lógica no debería depender de los detalles de implementación de los dispositivos,
                    sino, los dispositivos cambiar en caso de que la lógica cambie ("lo menos importante
                    depende de lo más importante").

             Dudas, como siempre, envíala!                              Sugerencia

                                                                        Se recomienda la lectura profunda
                                                                        y meditada del artículo de
                                                                        referencia.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
224 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Solución
             El objetivo de este ejercicio estaba dividido en dos partes:

                     La primera parte, repasar el concepto y la forma de requerir las clases y cómo hacerlo en caso
                     de tener subdirectorios (representados en UML como “paquetes” para agrupar clases).

                      La segunda parte, buscaba seguir aplicando con ejemplos por qué cada vez que
                     implementamos un “servicio” debemos de forma casi mecánica incluir una interfaz para dejar el
                     camino definido a cualquier clase que necesite usar ese servicio.

             Una vez concluidos estos dos ejercicios, en esta misma corrección, explicaré algunos conceptos sobre
             “Análisis & Diseño Orientado a Objetos” que creo (aunque escapa el alcance del temario de este libro)
             es el momento ideal para abordar.

             No desaprovechemos la oportunidad ;-)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
225 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Parte 1: hacer una “máquina de escribir” siguiendo el ejemplo
             del artículo
             Se creará una clase “MaquinaDeEscribir” que estará en el paquete “lógica” (donde se define la forma en
             que trabajará el sistema). Posteriormente esta “lógica” hará uso de los dispositivos de más bajo nivel
             para poder acceder a la entrada y salida de datos.

             El diseño UML era el siguiente:




             Y la vista de paquetes era la siguiente




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
226 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Implementación

             index.php




             MaquinaDeEscribir.php (dentro del paquete “lógica”)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
227 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Teclado.php (dentro del paquete “dispositivos”)




             Impresora.php (dentro del paquete “dispositivos”)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
228 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Conclusión

             Según se explica en el artículo de referencia (PHPSenior), la lectura de los diagramas y sus
             relaciones nos hacen llegar a la siguiente conclusión:




                 “La lógica de nuestro sistema depende de los dispositivos, por lo pronto esto significa un
                 problema en nuestro diseño , ya que según el sentido de las flechas, cualquier cambio en
                       nuestros dispositivos de bajo nivel afectarán el corazón de nuestro sistema”



             Esto es tan peligroso como decir que habría que cambiar la implementación del sistema de
             gestión de nuestra empresa cada vez que cambie la forma de entrada o salida de datos, algo
             que es ridículo. Sería correcto si cambia la lógica central de nuestro sistema se vean afectados
             los dispositivos de bajo nivel y estos deban ser adaptados, pero no al revés!



             Esto lo podremos revertir usando interfaces, por lo tanto veremos todo el proceso de mejorar
             nuestro diseño a continuación…




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
229 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com



             Parte 2: Agregar interfaces al diseño propuesto en la parte 1




             Aquí separamos la clase MaquinaDeEscribir de depender directamente de las clases Teclado e
             Impresora.

             Hay varios detalles importantes:

                        Pasamos de depender de “implementaciones concretas” a depender de
                         “implementaciones abstractas”, ya que para MaquinaDeEscribir lo único con que se
                         relaciona es con elementos de tipo las interfaces y no se preocupa cómo se
                         implementen las clases que cumplan con el “contrato de implementación” (es
                         problema de la interfaz definir lo que se necesita y de la clase que quiere el servicio
                         en cumplir los requisitos necesarios para usarlo).

                        Casi sin darnos cuenta estamos cumpliendo con el principio “Abierto/Cerrado”, ya
                         que vamos a estar “cerrados al cambio pero abiertos a la extensión”, el “foco de
                         cambio” será agregar nuevos dispositivos pero no necesitaremos modificar el
                         funcionamiento de MaquinaDeEscribir, ya que su algoritmo será siempre el mismo.

             Aún hay otro detalle más, no está representada la clase Index, la que nos da el contexto de
             cómo se ejecuta todo este diseño…



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                  SURFORCE / FORMACIÓN
230 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



             Se podría decir que solo falta la flecha de Index a la clase MaquinaDeEscribir:




             Pero no, no es suficiente, ya que para que MaquinaDeEscribir pueda funcionar depende de que
             le ingresen dos elementos de tipo Lector y Escritor. Prestar atención, la clase
             MaquinaDeEscribir no depende directamente de las clases concretas, sí las terminará usando
             a través de polimorfismo (a esto se le llama “indirección” o “relación indirecta”: usa elementos
             concretos pero depende en realidad de elementos abstractos).

             El diagrama correcto debería ser el siguiente:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                              SURFORCE / FORMACIÓN
231 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                        www.surforce.com



             Implementación
             Lo medular de la implementación es el nuevo método “run” de la clase MaquinaDeEscribir, que
             recibe ahora dos tipos de objetos, “lectores” y “escritores”:

             index.php




             MaquinaDeEscribir.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                               SURFORCE / FORMACIÓN
232 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                          www.surforce.com




             LectorInterface.php




             EscritorInterface.php




             Impresora.php




             Nota: como Impresora y la interfaz Escritor son del mismo paquete, no llevan rutas en el
             require_once que hagan referencia desde donde se ejecuta Index, ya que esta ubicación puede
             cambiar y la relación entre los paquetes debe estar fija por diseño (revisar las flechas del
             diagrama anterior).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
233 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                             www.surforce.com



             Teclado.php




             Nota: el require_once es igual que en el caso anterior, se asume la invocación desde el paquete.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
234 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com



             ¿Y el Diagrama de Paquetes?

             … ¿cómo quedará ahora la relación vista a nivel de paquetes? Viendo el sentido de las flechas y
             solo representando una flecha de dependencia (así son siempre entre paquetes) resumiendo
             todas las existentes (aumentamos el nivel de abstracción) …


                                                  Paquete “lógica”




                                                 Paquete “dispositivos”




             Entonces, la vista de paquetes se ve así:




             Lo que no debe asustar es que existan dos flechas de dependencia contra el paquete desde
             Index, ya que esto es normal (para usar un servicio o conjunto de clases podremos depender de
             uno o más paquetes), lo que sí debería preocuparnos (además de evitar las relaciones cíclicas)
             es que –a pesar de haber mejorado hacia un diseño “que depende de interfaces y no de
             implementaciones concretas”- nuestro paquete de “lógica” sigue dependiendo del paquete de
             “dispositivos”…

             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
235 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com



             El “Principio de Inversión de dependencias (DIP)”
             ¿Cómo solucionamos esto? Cambio de sentido de flechas entre paquetes

             Hay una técnica para cambiar el sentido de las dependencias entre paquetes que es mover las
             clases de un paquete hacia el otro paquete, o en su defecto, creando un tercer paquete y
             mover las clases para cambiar el sentido de las direcciones. Para este caso concreto,

             moveremos las interfaces a la clase que provee el servicio, por lo tanto cambiaremos el sentido
             de las dependencias entre paquetes:



                                                  Paquete “lógica”




                                                  Paquete “dispositivos”




             Nuevamente, prestar atención el sentido de las flechas de implementación, ahora apunta a las
             clases que están en el paquete de arriba (“lógica”), así que pasando en limpio el diagrama de
             paquetes ahora quedaría:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
236 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com




             Alternativa: como solución alternativa podríamos crear un tercer paquete para las Interfaces,
             donde la lógica y los dispositivos dependerían, rompiendo la relación directa que antes existía.

             ¡Ey! ¡Finalmente logramos nuestro objetivo!, ahora el sistema está mejor diseñado,
             implementado “Orientado a la Interfaz”, cumple con el principio de diseño “Abierto/Cerrado” y
             el paquete de más “alto nivel” no depende de los detalles o cambios del paquete de más “bajo
             nivel”!!




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
237 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             Resumen
             Premisa: “En general, las interfaces pertenecen a las entidades que las emplean”

             El paquete de “lógica” conoce y tiene una interfaz para conectarse con el paquete “dispositivos”, pero
             no sabe qué hay dentro del paquete “dispositivos”.

             Para más información:

             DIP - Dependency Inversion Principle (Principio de Inversión de Dependencias)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
238 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                       www.surforce.com



             Comentarios adicionales
             Pienso que era difícil intuir el desenlace de esta         árbol”, estudiar el impacto de los paquetes, los
             nueva historia de suspenso ;-)                             patrones y los principios de diseño, y esa
                                                                        “magia de druidas” se llama “Análisis y Diseño
             A esta altura del libro espero haber logrado
                                                                        Orientado a Objetos”.
             transmitir un poco de experiencia y dejarles una
             “semilla”    para seguir investigando y                    Nos estamos encontrando en el próximo
             profundizando el tema de la “Programación                  desafío, el último ejercicio del libro, donde
             Orientada a Objetos” y que no es solo “crear               aplicaremos el último de los conceptos que
             clases y hacer objetos”.                                   quiero dejarles: “la arquitectura de tres capas”

             Existe otra disciplina que estudia cómo poder
             aplicar los conceptos más allá de la “visión del




                   Necesitas el código completo de la solución del ejercicio?

                   Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
239 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                              www.surforce.com



             Capítulo 20 - Ejercicio “Desarrollar un sistema de ABM de
             usuarios”

             Este fue el último ejercicio de los cursos a distancia que integraban todos los conceptos vertidos
             en los capítulos de este libro.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
240 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Requerimientos

             "Ustedes están a prueba por la empresa SURFORCE y a modo de probar sus conocimientos para
             obtener el puesto de PHP Senior recibirán un sub-sistema que deberán concluir con todo éxito.

             Lo que hay desarrollado hasta el momento es el esqueleto de un sistema en 3 capas que
             cumple con el siguiente UML:




             Como se puede observar, todo parte de un único archivo inicial "index.php" y posteriormente
             accede a la capa de presentación, luego a la capa de dominio y finalmente a la capa de
             persistencia. Se entiende que no se pueden saltear las capas propuestas ni el sentido de las
             dependencias entre paquetes.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
241 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com



             Lo que se deberá desarrollar en primera instancia es un sistema de ABM de Usuarios
             (Altas/Bajas/Modificaciones) con un diseño de interfaz similar a entornos como Ruby On Rails (a
             continuación un ejemplo de cómo se deberá ver la interfaz):




             La primer pantalla es un listado de los registros existentes en la tabla, posteriormente en cada
             línea existen las opciones de mostrar toda la información, editarla o eliminarla. Al final del
             listado se puede observar la opción de dar de alta un usuario.

             Podrán bajar un sistema base de ejemplo (sin terminar) y ustedes deberán:

                 1. Aplicar todos los conocimientos vistos hasta el momento (Kiss es fundamental).
                 2. Relevar todo lo existente en el sistema entregado (archivo de configuración, entender
                    cómo funciona, cual es la forma de trabajo, qué falta, etc).
                 3. Implementar todo lo necesario para cumplir el ejemplo de diseño anterior, logrando
                    hacer un listado de usuarios, detalle, alta, baja y modificación de datos.
                 4. Presentar el diagrama UML final con todos los agregados realizados.

             Se sugiere la lectura complementaria de los siguientes materiales:

                    PHP5: Diseño en 3 capas y problemas con subdirectorios
                    Conceptos: "Separar el código de la capa de presentación"
                    "Petición para soporte de Name Spaces en PHP5"



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
242 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Se entregará un archivo comprimido con el código fuente del sistema con todas las capas y
             hasta una carpeta llamada "sql" que contendrá una base de datos y una tabla usuarios para
             poder iniciar su desarrollo.

             ¡Ese puesto en la compañía puede ser tuyo!"

             Nota: El diseño general de 3 capas del sistema base que les entrego fue usado en un sistema
             real de aplicaciones SMS para celulares (no es meramente "otro problema teórico para
             resolver" ).




                 Para bajar el archivo comprimido con el código fuente

                 Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                SURFORCE / FORMACIÓN
243 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                           www.surforce.com



             Solución
             La idea de esta tarea es presentar un problema completo a partir de un template de un sistema
             existente, el cual deberían usar de apoyo para cumplir con los requerimientos solicitados.

             A pesar que el ejercicio permite aplicar algunos conceptos aprendidos en este libro, no deja de
             ser un ejercicio y como tal, desborda de programación “artesanal”. Hay muchos detalles que
             no son tenidos en cuenta, como puede ser la seguridad del sistema o cómo procesar más
             eficientemente la capa de presentación en conjunto al armado de html, estilos, etc.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
244 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com



             Cambios que se aplicaron en la resolución
             A grandes rasgos se hicieron las siguientes modificaciones

             General

                    Se usó el criterio de definir estático todo lo que era genérico o general de la clase, y lo
                     opuesto para referirse a los métodos que se aplican a una instancia de un objeto. Es
                     decir, si la clase usuario se usaba para traer todos los usuarios del sistema, debía ser
                     Usuario::getAll(), y los métodos estándar se aplicaban a una instancia única que
                     representaba a “él” usuario.

                    Se creó un método load de la clase dominio/Usuario para una vez obtenido el id de
                     usuario por parámetro, este cargue el usuario que se encuentre en la persistencia. Se
                     puede decir que hace el efecto de una “fábrica” (patrón de diseño).

             Persistencia

                    Modificamos la persistencia para que retorne los datos en un array

                    Modificamos la clase Sql para contemplas los demás casos del ABM

             Dominio

                    Agregamos el constructor para inicializar los datos que consideramos básicos del objeto

                    Modificamos el getAll para que pueda retornar una colección de objetos array

                    Creo el toString para que cada usuario sepa cómo imprimirse cuando lo use la capa de
                     presentación

             Presentación

                    Se armaron todos los formularios requeridos para el ABM

                    Se agregaron redirecciones para luego de procesar regrese a la página inicial.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
245 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diagrama tradicional de paquetes




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
246 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Diagramas de clases y sus paquetes de origen




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
247 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



             Diagramas de Secuencia
             Se sabe que los diagramas de clases son una “foto estática” del diseño general de una
             solución, pero no siempre es suficiente para entender cómo un diseño de clases debe trabajar,
             qué se invoca primero y qué después, para ello existen los “diagramas de secuencia” que nos
             permiten tener una visión más dinámica y temporal de cómo interactúan los objetos una vez
             que se inicia una acción determinada.

             Caso: Ver detalle de un usuario (ejemplo)




             Aquí se pude observar cómo se van sucediendo las invocaciones de los métodos, y cómo es
             que una clase se relaciona con otra invocando los métodos de la clase siguiente. La línea
             temporal se define de arriba – abajo, el primer método que se invoca es el que hace Index al
             ejecutar UsuarioPresentacion::detalle() y sigue bajando hasta llegar a la última ejecución.

             Por ejemplo,

                 1. Index invoca el detalle() de UsuarioPresentación,

                 2. posteriormente este invoca el método load() de la clase Usuario y

                 3. finalmente este invoca el load de la clase UsuarioPersistencia (todo un “pasamanos”).

             Aunque generalmente no se representa, al final de la cadena lo que sucede es que la última
             invocación retorna información, que recibe la clase siguiente al invocación, hasta llegar otra vez
             a la clase inicial (secuencia inversa):

                 1. UsuarioPersistencia retorna datos,

                 2. Usuario lo recibe y arma los objetos para luego retornarlos a

                 3. la clase UsuarioPresentación para luego esta retornar a

                 4. Index, recibe lo que tiene que mostrar (html) y así ejecuta un “echo”



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                            SURFORCE / FORMACIÓN
248 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                      www.surforce.com



             Toda documentación UML debería contar con los correspondientes diagramas de secuencia
             que documenten cómo se usan las clases entre ellas y en qué momento una invoca métodos de
             la otra.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
249 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             Partes esenciales del código de la solución
             Index.php

             <?php
             require_once 'configuracion.php';
             require_once PRE . DIRECTORY_SEPARATOR . 'UsuarioPresentacion.php';

             abstract class Index
             {
                 const SIN_PARAMETROS = 0;

                  static public function run($get)
                  {
                      DEBUG ? var_dump($get) : null;

                         if(count($get) != self::SIN_PARAMETROS){
                             self::_procesarModulo();
                         }else{
                             self::_porDefecto();
                         }
                  }
                  static private function _porDefecto()
                  {
                      echo 'Pagina por Defecto';
                      echo '<ul>';
                      echo '<li><a href="?modulo=listado">listado</li>';
                      echo '</ul>';
                  }
                  static private function _moduloNoExiste()
                  {
                      echo 'Modulo no Existe';
                  }



                          Nota

                          Para facilitar el entendimiento del código el
                          método a continuación se pasa entero a la
                          siguiente página (todo es parte de la misma
                          clase)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                             SURFORCE / FORMACIÓN
250 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                       www.surforce.com




                 static private function _procesarModulo()
                 {
                     switch ($_GET['modulo']){
                         case 'listado':
                             if (isset($_GET['mensage']) && $_GET['mensaje'] != "") {
                                 echo "El Usuario ha sido ".$_GET['mensaje']." correctamente";
                             }
                             echo UsuarioPresentacion::listadoUsuarios();
                             break;
                         case 'detalle':
                             echo UsuarioPresentacion::detalle($_GET['id']);
                             break;
                         case 'nuevousuario':
                             echo UsuarioPresentacion::mostrarFormNuevoUsuario();
                             break;
                         case 'insertar':
                             if(UsuarioPresentacion::guardarUsuario(
                                     $_POST['nombre'],
                                     $_POST['apellido'])) {

                                    header("Location:index.php?modulo=listado&mensaje=guardado");
                                }
                                break;
                            case 'modificarusuario':
                                echo UsuarioPresentacion::mostrarFormModificarUsuario($_GET['id']);
                                break;
                            case 'modificar':
                                if(UsuarioPresentacion::modificarUsuario(
                                        $_POST['id'],
                                        $_POST['nombre'],
                                        $_POST['apellido'])){

                                    header("Location:index.php?modulo=listado&mensaje=modificado");
                                }
                                break;
                            case 'eliminar':
                                if(UsuarioPresentacion::eliminarUsuario($_GET['id'])) {
                                    header("Location:index.php?modulo=listado&mensaje=eliminado");
                                }
                                break;
                            default:
                                self::_moduloNoExiste();
                                break;
                       }
                  }
             }
             Index::run($_GET);




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                          SURFORCE / FORMACIÓN
251 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                       www.surforce.com



             UsuarioPresentacion.php

             <?php
             require_once 'configuracion.php';
             require_once DOM . DIRECTORY_SEPARATOR . 'Usuario.php';

             abstract class UsuarioPresentacion
             {
                 static public function listadoUsuarios()
                 {
                     $usuarios_arr = Usuario::getAll();

                     $retorno = '<ul>';
                     foreach($usuarios_arr as $objetoUsuario){
                         $retorno .= '<li>'.$objetoUsuario;
                         $retorno .= " <a href='?modulo=detalle&id=".$objetoUsuario-
             >getId() ."'>Mostrar</a> | ";
                         $retorno .= " <a href='?modulo=modificarusuario&id=". $objetoUsuario-
             >getId() ."'>Modificar</a> | ";
                         $retorno .= " <a href='?modulo=eliminar&id=". $objetoUsuario-
             >getId() ."'>Eliminar</a> | ";
                         $retorno .='</li>';
                     }
                     $retorno .= "<li><a href='?modulo=nuevousuario'>Nuevo Usuario</a>";
                     $retorno .= '</ul>';
                     return $retorno;
                 }
                 static public function detalle($id)
                 {
                     return Usuario::load($id);
                 }
                 static public function mostrarFormNuevoUsuario()
                 {
                     return self::_mostrarFormulario();
                 }
                 static public function mostrarFormModificarUsuario($id)
                 {
                     $usuario = Usuario::load($id);

                       $form = self::_mostrarFormulario(
                           $id,
                           $usuario->getNombre(),
                           $usuario->getApellido(),
                           "modificar"
                       );
                       return $form;
                  }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                           SURFORCE / FORMACIÓN
252 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                     www.surforce.com




                 static public function modificarUsuario($id, $nombre, $apellido)
                 {
                     $usuario = new Usuario($id, $nombre, $apellido);
                     return $usuario->modificarUsuario();
                 }
                 static public function eliminarUsuario($id)
                 {
                     $usuario = new Usuario($id);
                     return $usuario->eliminarUsuario();
                 }
                 static private function _mostrarFormulario($id = "", $nombre = "", $apellido = "",
              $accion = "insertar")
                 {
                     $retorno = "";
                     $retorno = "<form action='?modulo=".$accion."' method='post'>";
                     $retorno .= "<input type='hidden' name='id' value='".$id."' />";
                     $retorno .= "Nombre:<input type='text' name='nombre' value='". $nombre."' /> "
             ;
                       $retorno .= "Apellido:<input type='text' name='apellido' value='".$apellido."'
              />";
                       $retorno .= "<input type='submit' name='submit' value='".ucwords($accion)."' /
             >";
                       $retorno .= "</form>";

                       return $retorno;
                   }
                   static public function guardarUsuario($nombre, $apellido)
                   {
                       $usuarioNuevo = new Usuario(NULL,$nombre, $apellido);
                       return $usuarioNuevo->guardarUsuario();
                   }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                           SURFORCE / FORMACIÓN
253 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                 www.surforce.com



             Usuario.php

             <?php
             require_once 'configuracion.php';
             require_once PER . DIRECTORY_SEPARATOR . 'UsuarioPersistencia.php';

             /**
               * Description of Usuario
               *
               * @author Pc
               */
             class Usuario
             {
                  private $_id;
                  private $_nombre;
                  private $_apellido;

                  public function __construct($id = "", $nombre = "", $apellido = "")
                  {
                      $this->_id = $id;
                      $this->_nombre = $nombre;
                      $this->_apellido = $apellido;
                  }

                  public function getId()
                  {
                      return $this->_id;
                  }
                  public function getNombre()
                  {
                      return $this->_nombre;
                  }
                  public function getApellido()
                  {
                      return $this->_apellido;
                  }
                  public static function getAll()
                  {
                      $usuarioPersistencia = new UsuarioPersistencia();
                      $datos_array = $usuarioPersistencia->getAll();

                       foreach($datos_array as $usuario_array){
                           $id         = $usuario_array['id'];
                           $nombre     = $usuario_array['nombre'];
                           $apellido   = $usuario_array['apellido'];

                           $retorno[] = new Usuario($id, $nombre, $apellido);
                       }
                       return $retorno;
                  }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                          SURFORCE / FORMACIÓN
254 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                www.surforce.com




                  public static function load($id)
                  {
                      $usuarioPersistencia = new UsuarioPersistencia();
                      $datos_array = $usuarioPersistencia->load($id);

                       foreach($datos_array as $usuario_array){
                           $usuario = new Usuario(
                               $id,
                               $usuario_array['nombre'],
                               $usuario_array['apellido']
                           );
                       }
                       return $usuario;
                  }
                  public function guardarUsuario()
                  {
                      $usuarioPersistencia = new UsuarioPersistencia();
                      $guardo = $usuarioPersistencia->guardarUsuario(
                          $this->_nombre,
                          $this->_apellido
                      );

                      return $guardo;
                  }
                  public function modificarUsuario()
                  {
                      $usuarioPersistencia = new UsuarioPersistencia();
                      $modificar = $usuarioPersistencia->modificarUsuario(
                          $this->_id,
                          $this->_nombre,
                          $this->_apellido
                      );

                      return $modificar;
                  }
                  public function eliminarUsuario()
                  {
                      $usuarioPersistencia = new UsuarioPersistencia();
                      $eliminar = $usuarioPersistencia->eliminarUsuario($this->_id);

                      return $eliminar;
                  }
                  public function __toString()
                  {
                      return $this->_id." ".$this->_nombre." ".$this->_apellido;
                  }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                         SURFORCE / FORMACIÓN
255 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                               www.surforce.com



             UsuarioPersistencia.php

             <?php
             require_once 'configuracion.php';

             require_once PER . DIRECTORY_SEPARATOR . 'BaseDeDatos.php';
             require_once PER . DIRECTORY_SEPARATOR . 'MySQL.php';
             require_once PER . DIRECTORY_SEPARATOR . 'Sql.php';

             class UsuarioPersistencia
             {
                 public function getAll()
                 {
                     $bd = new BaseDeDatos(new MySQL());
                     $sql = new Sql();

                       $sql->addTable('usuarios');
                       return $bd->ejecutar($sql);
                  }

                  public static function load($id)
                  {
                      $bd = new BaseDeDatos(new MySQL());
                      $sql = new Sql();

                       $sql->addTable('usuarios');
                       $sql->addWhere("id = ".$id);

                      return $bd->ejecutar($sql);
                  }
                  public function guardarUsuario($nombre, $apellido)
                  {

                       $bd = new BaseDeDatos(new MySQL());
                       $sql = new Sql();

                       $sql->addFuncion("insert");
                       $sql->addTable("usuarios");
                       $sql->addSelect("nombre");
                       $sql->addSelect("apellido");
                       $sql->addValue($nombre);
                       $sql->addValue($apellido);

                       return $bd->ejecutar($sql);
                  }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                        SURFORCE / FORMACIÓN
256 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                              www.surforce.com




                  public function modificarUsuario($id, $nombre, $apellido)
                  {
                      $bd = new BaseDeDatos (new MySQL());
                      $sql = new SQL();

                       $sql->addFuncion("update");
                       $sql->addTable("usuarios");
                       $sql->addSelect("nombre='".$nombre."'");
                       $sql->addSelect("apellido='".$apellido."'");
                       $sql->addWhere("id=".$id);

                      return $bd->ejecutar($sql);
                  }
                  public function eliminarUsuario($id)
                  {
                      $bd = new BaseDeDatos (new MySQL());
                      $sql = new SQL();

                       $sql->addFuncion("delete");
                       $sql->addTable("usuarios");
                       $sql->addWhere("id=".$id);

                       return $bd->ejecutar($sql);
                  }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
257 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com



             Resumen
             Quiero felicitarte si llegaste hasta el final del libro y completaste todos los ejercicios.

             Honestamente, el gusto de escribir todo este material fue mío y espero que sigamos en
             contacto a través del sistema para usuarios, cursos a distancia, libros o simplemente un
             comentario en el blog consultando alguna duda :-)




              Baja el ejercicio completo con todo el código comentado

              Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                               SURFORCE / FORMACIÓN
258 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                         www.surforce.com



             Capítulo 21 - Anexo: “Manejo de excepciones”
             Un tema no menos importante en la POO es el manejo de errores, algo que todos los lenguajes
             modernos soportan y dan la posibilidad de unificar la forma de manejarlos en el sistema.

             Esta funcionalidad se agregar a partir de PHP5.



             Manual oficial:

             http://www.php.net/manual/es/language.exceptions.php




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
259 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Introducción
             Una excepción es una situación anormal que                 En la programación tradicional, haríamos algo
             ocurre durante la ejecución de un sistema que              como esto (extrato del manual oficial):
             no está contemplada en el flujo esperado de
             nuestro código.
                                                                         <?php
                                                                         $link = mysql_connect(
             Por ejemplo, una parte de nuestro sistema tiene                   'localhost',
             la responsabilidad de listar los usuarios                         'mysql_user',
             actualmente existentes. Esa es la funcionalidad                   'mysql_password'
                                                                         );
             esperada y así lo implementamos.
             Necesariamente a bajo nivel vamos a requerir                if (!$link) {
                                                                             die(
             operaciones de persistencia, es decir,                             'Could not connect: '
             conectarnos a la base de datos, requerir los                       . mysql_error()
             datos y desconectarnos. Ese es el flujo normal y                );
                                                                         }
             se espera que todo salga bien.
                                                                         echo 'Connected successfully';
             Lamentablemente debemos contemplar todas                    mysql_close($link);
             las situaciones que “no son esperadas / no son              ?>
             normales” para que nuestro sistema sepa cómo
             proceder en caso de fallas:

                    el servidor de base de datos está fuera            Aquí solo estamos controlando que se pudo
                     de servicio,                                       hacer la conexión a la base de datos, pero no los
                    cambió la clave del usuario que usamos             demás casos.
                     para conectarnos,
                    no existe la tabla de usuarios,
                    algún campo de la tabla cambió de
                     nombre,
                    etc.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
260 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




             Podríamos agregarle entonces:

               <?php
               $link = mysql_connect(
                     'localhost',
                     'mysql_user',
                     'mysql_password'
               );

               if (!$link) {
                   die(
                      'Could not connect: '
                      . mysql_error()
                   );
               }

               echo 'Connected successfully';

               $result = mysql_query("SELECT id,email FROM people WHERE id = '42'");

               if (!$result) {
                   echo 'Could not run query: ' . mysql_error();
                   exit;
               }
               $row = mysql_fetch_row($result);

               echo $row[0]; // 42
               echo $row[1]; // the email value

               mysql_close($link);

               ?>



             Si somos observadores nos iremos dando cuenta que el código para validar todas las situaciones
             anómales empieza a crecer y superar en extensión al verdadero código funcional, donde muy
             probablemente entraremos a anidar “if/else/elseif” y/o “switchs”, y así seguirá creciendo en
             complejidad y aumentando la posibilidad de fallos.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                            SURFORCE / FORMACIÓN
261 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Básicamente cómo funcionan                                 En esta situación no logramos mucho más
             las excepciones                                            avance, ya que al fallar alguna rutina dentro del
                                                                        “try” simplemente pasa el controlo al “catch” y
             Existen dos claras zonas, la primera de “try” que
                                                                        toda la información queda dentro de la
             se traduce cómo “intentar ejecutar el código
                                                                        instancia “$e” de tipo clase Exception.
             que está entre llaves y que es posible que
             pueda fallar” y el “catch”, el código previsto
             para tratar el fallo que pueda ocurrir.

              try{

                   /* Aquí va el código
                   que podría fallar*/

              }catch(Exception $e){

                   /* Si alguna línea
                   dentro del try falló,
                   podremos tomar el
                   control aquí */
              }




             Si quisiéramos emular una situación donde si
             falla simplemente envíe un mensaje en pantalla,
             podríamos hacer lo siguiente:


               try{                                              Aclaración

                   /* Aquí va el código                          Si vienes prestando atención, el echo
                   que podría fallar */                          $e retorna información porque la
                                                                 clase Exception implementa el
               }catch(Exception $e){
                                                                 método toString() con el mensaje
                   echo $e;                                      básico de error.

               }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
262 de 294          Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



                 Estructura interna de una clase Exception
                 La estructura de una clase Exception es (según el manual oficial):

             class Exception
             {
                 protected $message = 'Unknown exception';                       //   exception message
                 protected $code = 0;                                            //   user defined exception code
                 protected $file;                                                //   source filename of exception
                 protected $line;                                                //   source line of exception

                      function __construct($message = null, $code = 0);

                      final   function    getMessage();                          //   message of exception
                      final   function    getCode();                             //   code of exception
                      final   function    getFile();                             //   source filename
                      final   function    getLine();                             //   source line
                      final   function    getTrace();                            //   an array of the backtrace()
                      final   function    getTraceAsString();                    //   formated string of trace

                      /* Overrideable */
                      function __toString();                                     // formated string for display
             }




                 Esto significa que podemos hacer uso de los métodos listados para poder, si así lo deseamos, generar un
                 mensaje a medida para el usuario de acuerdo a nuestras necesidades.

                 Si hacemos un echo $e; obtendremos el mensaje estándar de la Excepción, que generalmente podría ser
                 bastante extenso e informativo, tal vez ideal para ambientes de desarrollo pero no tanto para
                 producción, ya que nuestra seguridad se podría compromenter al darle tantos detalles a un “extraño”.

                 Un ejemplo de un mensaje más breve y sin menos datos:

                  try{

                       /* Aquí va el código que podría fallar*/

                  }catch(Exception $e){

                       echo "Ocurrió un error inesperado, "
                          ."por favor consultar a soporte técnico";
                  }




                 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
                 Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
263 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Tal ver preferimos dar una referencia, un código para poder completar en un formulario de asistencia
             técnica.

               try{

                   /* Aquí va el código que podría fallar*/

               }catch(Exception $e){

                   echo "Ocurrió un error inesperado, "
                      ."por favor consultar a soporte técnico "
                      " (Código de Error ".$e->getCode().")";

               }



             Pero tal vez no queremos que el usuario sepa tanto, somos un poco más proactivos y preferimos
             dejarles un mensaje genérico y que se genere un registro en el log, o si es muy grave, nos envíe una
             notificación por email o hasta un SMS a nuestro celular.

               try{

                   /* Aquí va el código que podría fallar*/

               }catch(Exception $e){

                   echo "Ocurrió un error inesperado, "
                      ."ya se envió una notificación al departamento de sistemas "
                      " En un momento se estarán contactando con usted";

                   Mail::send("sistemas@surforce.com", "Error:".$e );
               }




             Esto es lo básico de cómo responder a un error, pero casi de la misma forma que podríamos hacerlo con
             un if/else.

             Ahora veremos las diferencias.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
264 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                         www.surforce.com



             Importante: PHP no tiene                                   Por lo tanto tenemos dos problemas:
             excepciones por defecto
                                                                              En PHP5 debemos crearnos nuestras
             Una de las ventajas viene directamente por el                     propias excepciones a partir de la única
             paradigma POO, como las excepciones se                            clase que nos provee el lenguaje:
             representan con objetos, podemos extender la                      Exception.
             clase Exception y crear nuestras propias                         Todo lo que atrapemos debemos
             excepciones de acuerdo a nuestras necesidades.                    asegurarnos que retorne una
                                                                               Excepción, y como el lenguaje no lo
             En lenguajes como Java ya existen por defecto
             cientos de clases agrupadas por temas como                        hace por defecto, debemos hacerlo a
             base de datos, manejo de archivos, para                           nivel de clases propias, validando
             problemas matemáticos, arrays, etc. Y lo más                      internamente de la forma tradicional
             importante, todo retorna por defecto una                          (if/else/switch), pero al subir de nivel el
                                                                               resto podrá hacer uso normal de los
             excepción, algo que no sucede en
                                                                               try/catch.
             PHP5!
                                                                        Sí, lamentablemente aún estamos en pañales
             ¿Cuan grave es no tener Excepciones                        con las excepciones,pero se espera que por lo
                                                                        menos en PHP7 se modifiquen todas las rutinas
             predefinidas y por defecto?
                                                                        del lenguaje para que así lo hagan.
             Que es muy normal que lo primero que
             probemos sea una sentencia de conexión a una
             base de datos (como vimos al principio de este
                                                                           Zend Framework tiene Excepciones
             capítulo) y que las excepciones no funcionen,
                                                                           Predefinidas y por Defecto
             dejandonos algo confusos.
                                                                           Una de las ventajas de este framework es
                                                                           que todos sus componentes tiene manejo de
                                                                           excepciones, es decir, incorpora desde
                                                                           Zend_Exception (algo más completo que
                                                                           Exception estándar de PHP) y muchas más
                                                                           clases para cada situación, muy similar a
                                                                           Java.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
265 de 294        Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Ejemplo funcional de excepciones en PHP5
             Aquí veremos cómo hacerlas funcionar sin excepciones por defecto creando una clase genérica que
             tendrá todo el código del primer ejemplo donde retornaba los mensajes de error clásicos y los
             cambiaremos ahora por excepciones (comentaré las líneas que cambian y agrego a continuación las
             nuevas):

              <?php
              class BaseDeDatosEjemplo
              {
                  private $_link;

                     public function __construct()
                     {
                         $this->_link = mysql_connect(
                             'localhost',
                             'mysql_user',
                             'mysql_password'
                         );

                          if (!$link) {
                              // die('Could not connect: ' . mysql_error());
                              throw new Exception('Could not connect: ' . mysql_error());
                          }
                     }
                     public function traerDatos()
                     {
                         $result = mysql_query("SELECT id,email FROM people WHERE id = '42'");

                          if (!$result) {
                              //echo 'Could not run query: ' . mysql_error();
                              throw new Exception('Could not run query: ' . mysql_error());
                              //exit;
                          }
                          $row = mysql_fetch_row($result);

                          mysql_close($link);

                          return $row;
                     }
              }




             Se podría decir que el "throw" es similar a "return algo", lo que hace es "lanzar la excepción" a un nivel
             más arriba, donde se invocó originalmente la rutina, para que tomen el control de la situación anómala y
             procedan en consecuencia.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                          SURFORCE / FORMACIÓN
266 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             Por lo tanto, si todo el código anterior                   Importante: el orden de las
             queremos “atraparlo” en un "try" para tenerlo              excepciones
             controlado en caso de fallas, deberíamos hacer
                                                                        hay que tener en cuenta el orden de las
             lo siguiente:
                                                                        excepciones dentro del catch, ya que debe ir
                                                                        primero la excepción más específica e ir
               try{                                                     bajando a la excepción más genérica. Si
                      $bd = new BaseDeDatosEjemplo();                   colocamos la excepción genérica primero, todos
                      $datos = $bd->traerDatos();
                                                                        los fallos entrarán ahí y no a la excepción
               }catch(Exception $e){                                    acorde al tipo de error.
                   echo
                     "Falla al recuperar "
                     ."los datos";
               }




             Esta es la forma de trabajo más elemental,
             posteriormente habría que crear distintos tipos
             de Excepciones de acuerdo al tipo de falla,
             como por ejemplo:

              try{

                  /* Aquí va el código que podría fallar*/

              }catch(DbException $e){
                /* Aquí va el código para responder
                 a un error de Base de Datos */

              }catch(Exception $e){
                /* Aquí va el código para responder
                 a un error Genérico */
              }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
267 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             Beneficios de las Excepciones
                    Permiten separar el código de manejo de errores del código que debe cumplir con los
                     requerimientos de funcionalidad de la aplicación

                    Permite un manejo homogéneo de los errores: evitará que tengamos distintas estructuras para
                     contener los errores, como ser: en algunos casos una cascada de if, en otros un switch y tal vez
                     en otros algún objetos de manejo de errores.

                    No solo transfiere el control del sistema de un lugar a otro, sino que también trasmite
                     información sobre la situación anómala: como unidad todas las excepciones manejan objetos
                     de tipo Excepción y como todo objeto, tendrá atributos y métodos relacionados con el manejo
                     de errores.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
268 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             En Resumen
             Las excepciones son herramientas que cuentan todos los lenguajes POO modernos y no se discute su
             utilidad. Es fundamental entender los conceptos base, qué es una Excepción, que no todo debería
             considerarse como tal y solo las "situaciones anómalas / no esperadas" de nuestro sistema.

             Como desarrolladores siempre tendremos dos caminos para decidir: si ocurre una excepción, es
             responsabilidad de esa parte del código resolverla o deberá "relanzarla" al nivel superior para que este
             se encargue de hacer algo al respecto.

             Es muy habitual que si tenemos un sistema de 3 capas y falla en la capa de persistencia, esta relance la
             excepción al dominio y este a la capa de presentación para que se transforme en una ventana de error
             que será entregada elegantemente al usuario como:

                 "Ha ocurrido un error al intentar guardar los datos, por favor pruebe nuevamente dentro de unos
                                                            minutos" ;-)




                 Quieres saber si hay alguna actualización de este capítulo?

                 Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                               SURFORCE / FORMACIÓN
269 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                          www.surforce.com



             Capítulo 22 - Cierre del libro y reflexiones finales
             ¿No pasa que en algunas películas, cuando parece que todo terminó, al final se muestra una
             secuencia que nos adelanta el inicio de una continuación? ¿la revelación de una nueva trama?

             Bien, aquí viene ;-)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                          SURFORCE / FORMACIÓN
270 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                www.surforce.com




             Aquí hay algo que está mal.. ¿no se dieron cuenta?

             Si dijimos durante casi la mitad del taller que lo más
             importante es el “dominio” y que las flechas
             evidencian que si hay una relación de A -> B significa
             que todo cambio de B afecta a A, qué pasa con este
             modelo tradicional de “3 capas”?

             Index -> presentación -> dominio -> persistencia

             Mmmm… todo bien que presentación dependa de
             dominio que es lo más importante, si este cambia, es
             lógico que cambie las pantallas… pero está bien que
             dominio dependa de la persistencia?! eh?! ah?!

             ¿Entonces, todo lo que aprendimos está mal? ¿equivocado? ¿erróneo?



                                                              ¡AGHHHH!




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
271 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com




                                                       …No    del todo! ;-)
             Lo que significa que el diseño
             tradicional de “3 capas” con el mismo
             sentido de flechas desde la
             ”presentación” pasando por “dominio”
             y terminando en “persistencia”, por
             más aceptado que esté, el diseño no
             cumple con todos los conceptos que
             vimos, por lo tanto, el verdadero
             diseño de 3 capas bien implementado
             debería ser como en el diagrama de la
             derecha (“persistencia apuntando a
             dominio”).

             Es verdaderamente interesante el mundo más allá de la Programación Orientada a Objetos y
             que entra en lo que es el Análisis y Diseño Orientado a Objetos, un nivel más, el arte de los
             druidas, el camino del “Arquitecto de la Matrix”, poder detectar la estabilidad de los paquetes,
             los principios que afectan a todos los diseños, cómo mejorar nuestro diseño o detectar sus
             fallas, que… vendrá en un futuro no muy lejano!

             Ahora sí, hasta el próximo libro, curso, taller o post en el blog! ;-)

             FIN.




                 Confirma que estás leyendo la última versión de este libro

                 Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                            SURFORCE / FORMACIÓN
272 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                  www.surforce.com




                                                             Enrique Place

                                                   http://phpsenior.blogspot.com

                                                 http://enriqueplace.blogspot.com

                                                      http://www.surforce.com




                    ¿Qué te pareció el libro? ¡Envíame tus comentarios!

                    Ingresa a http://usuarios.surforce.com




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                            SURFORCE / FORMACIÓN
273 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                       www.surforce.com



             Anexo I: "Qué es lo nuevo en PHP5?"
             Este anexo está basado en el artículo What's new in PHP5 (18/3/2004) publicado por Zend
             Developer Zone, al cual le agrego un poco más de información y comentarios extras sobre mi
             opinión de cada uno de ellos.

             Veamos un resumen de "lo nuevo" en PHP5.




                         "La mejor manera de estar preparados para
                            el futuro es inventarlo" (John Sculley)




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
274 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                        www.surforce.com



             Características del Lenguaje

             PHP5 es la versión que hace un salto importante con respecto a la POO, incorporando funcionalidades
             que cualquier lenguaje OO necesita como mínimo (algo que PHP4 carecía completamente). Así que la
             mayoría de lo que veremos a continuación no son más que "una puesta al día" de PHP con respecto a los
             demás lenguajes POO (antes no se le podía decir que lo era por carecer de todo lo que veremos).



             1.Modificadores de acceso "public/private/protected"
             Se incorpora el uso de modificadores de acceso "public / private / protected" para atributos y métodos.

             Definir el "alcance o visibilidad" (scope) es importante para poder aplicar el "principio de ocultación", es
             decir, proteger al objeto del exterior y solo permitir acceso a los datos y comportamientos que nosotros
             especifiquemos. PHP4 carecía completamente de esta posibilidad y antes "todo era público".

             Aunque por defecto cualquier método que no diga nada al principio de su firma signifca que es "public",
             para unificar el criterio y claridad de la codificación se sugiere que todos los método públicos inicien
             siempre con el "modificador de acceso" correspondiente.



                                                                               ¡Dile "no" a los atributos públicos!

                                                                               Aunque "tecnicamente lo permita", esto no
                                                                               significa que se deban usar "atributos
                                                                               públicos".

                                                                               Recuerda, por defecto en POO se considera
                                                                               que todos los atributos deben ser "no
                                                                               públicos" y solo en algunos casos muy
                                                                               especiales (0.001 %) se justificaría su uso,
                                                                               pero serían contextos muy "raros" (tal vez en
                                                                               el desarrollo de un generador de código o un
                                                                               framework, pero no en un sistema
                                                                               desarrollado típicamente en POO).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
275 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             2. El método reservado __construct()
             En PHP4 para definir un constructor había que escribir un método con el mismo nombre de la clase (al
             igual que lo hace Java)




             PHP5 incorpora ahora un método exclusivo, a través del métod reservado __construct




             3. El método reservado __destructor()
             De la misma forma que el constructor, se agrega un método reservado que permite agregar
             funcionalidad cuando el objeto se destruya (por ejemplo, desconectarnos de una base de datos en el
             momento que se haga un unset de la instancia).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
276 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                     www.surforce.com



             4. Interfaces
             Se incorpora por primera vez la posibilidad de crear interfaces y poder agrupar clases "que hacen lo
             mismo" o "que tienen operaciones comunes".




             A diferencia de la herencia, se pueden implementar varias interfaces, por lo que podemos llegar a tener
             una clase que herede de una clase y que además implemente varias interfaces:




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
277 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             5. El operador "instance of"
             Se deja de usar el operador de PHP4 is_a() y se agrega uno nuevo más especializado para objetos: "es
             instancia de":

             if ($obj instance of Circle) {
                 print '$obj is a Circle';
             }

             Aquí estamos preguntando si la instancia "obj" es de tipo "la clase Círculo".

              ¡No uses el "instanceof"!

              Aunque "tecnicamente exista y pueda usarse ", no se recomienda estar preguntando a las instancias
              cual es su clase, ya que rompemos los diseños genéricos que pueden hacer uso del polimorfismo
              (estrategia base del DOO).

              Cuando trabajemos con varios objetos debemos manipularlos "genéricamente" y cada objeto debe
              saber cómo comportarse. Si por cada objeto vamos a preguntar de que tipo es y en base a eso
              hacer algo, estamos atando el comportamiento de nuestro código y tendremos una cadena de
              if's/switchs para contemplar cada caso (tenemos un nuevo "foco de cambio", ya que necesitaremos
              seguir preguntando por cada nuevo tipo que se cree).




             6. Operador "final" para los métodos
             Final es otra herramienta que nos permite reforzar el diseño de nuestra clase. En este caso podemos
             definir qué métodos que otra clase vaya a heredar no pueden ser modificados a través de la
             "sobreescritura" de los mismos (los métodos deben usarse tal cual se reciben de su padre).




             En este ejemplo podemos decir que diseñamos un método (por lo simple y concreto) que no debería
             existir ninguna situación donde necesite que sea modificado, por lo tanto "lo aseguramos" para que
             nadie que herede nuestra clase pueda modificar su comportamiento (ya que sería muy raro).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
278 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com



             7. Operador "final" para la clase
             Este operador también se aplica a las clases, impidiendo que una clase se pueda heredar, por lo que
             estamos entonces obligando a usar la clase sin posibilidad de crear otra en base a la original.

             final class FinalClass

             {
             }
             class BogusClass extends FinalClass

             {
             }

             En este caso el sistema dará un error grave porque se intentó heredar de una clase que está definida
             como "final".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                    SURFORCE / FORMACIÓN
279 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                www.surforce.com



             8. Método reservado __clone para clonado de objetos
             Desde que PHP5 empieza a trabajar por referencia y no por valor (como hacía por defecto PHP4), toda
             asignación con objetos representa una copia de la referencia a un mismo objeto, pero nunca se crea
             otro objeto duplicado. Si necesitáramos hacerlo (en casos muy especiales), podremos usar el comando
             clone.




             Pero, tal vez queramos especificar cómo debería clonarse el objeto, por lo que podemos definir en el
             comportamiento interno del mismo a través del método reservado __clone() todas las operaciones que
             necesitemos.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                 SURFORCE / FORMACIÓN
280 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                            www.surforce.com




             En este ejemplo podemos ver cómo se usa el método __clone, en el cual agregaremos que si alguien
             quiere clonar nuestro objeto no tenga el valor de la clave del objeto original.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                        SURFORCE / FORMACIÓN
281 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com




             9. Atributos Constantes para las clases
             Ahora se incorpora la posibilidad de incluir atributos constantes en las clases. Hay que tener en cuenta
             que como toda constante, estas son siempre públicas, y no podemos desde la clase esconderlas (su
             ámbito siempre será la clase).




             En este ejemplo podemos observar el uso de las constantes como forma de documentar y evitar los
             "números mágicos" (técnica de Refactoring), donde para conocer la lista de parámetros (sin importar
             saber de memoria sus valores) se lo podemos pedir a la misma clase consultando sus constantes (que
             son públicas y su propia descripción auto-documentan su uso).

             Esta práctica es ampliamente usada en muchos lenguajes como Java (tanto para clases como para
             interfaces) y se recomienda adoptar siempre que definamos parámetros o valores en nuestro sistema.

             Nota: las constantes se consideran "elementos de clase" (ver más adelante el apartado sobre "métodos
             estáticos"), por lo tanto dentro de la clase deberías usar self::CONSTANTE (igual puedes usar
             Clase::CONSTANTE).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                      SURFORCE / FORMACIÓN
282 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                  www.surforce.com



             10. Miembros estáticos o de clase (static)
             Las clases pueden incluir elementos "estáticos" (también denominados "elementos de clase"), accesibles
             a través de la clase y no de la instancia.

             El ejemplo más común es crear una clase Usuario que cada vez que se cree una instancia, la clase sepa
             cual es el último número de id y asignar dinámicamente un número más para el nuevo usuario.

             El atributo debería ser "de clase / estático", ya que su valor, en oposición a los atributos, son
             compartidos por todas las instancias de la misma clase.




             En este ejemplo podemos ver cómo a través del "atributo de clase" se mantiene la información entre
             instancias de la misma clase. Hay que tener en cuenta que este ejemplo no es del todo útil más allá de
             explicar cómo funciona, ya que cada vez que reiniciemos nuestra página, el contador empezará
             nuevamente de cero (para evitarlo habría que persistir esta información de alguna forma).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
283 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             Otro uso común de los miembros estáticos es en el patrón Singleton, el cual está pensado para retornar
             siempre la misma instancia de un objeto:

             class Singleton

             {
                   static private $_instance = NULL;

                   private function __construct() {}

                   static public function getInstance()

                   {
                        if (self::$_instance == NULL) {
                            self::$_instance = new Singleton();
                        }
                        return self::$_instance;
                   }
             }




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
284 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             11. Métodos estáticos o de clase (static)
             De la misma forma que ahora se pueden crear atributos de clase, también se pueden crear métodos de
             clase o estáticos. En esencia la lógica es la misma, son métodos que se comparten entre elementos de la
             misma clase y no son "de instancia" (no requieren una instancia para poder usarse).

             Un uso que se le da a los miembros de clase es crear una serie de métodos que no necesariamente
             están afectados a una instancia y que bien se pueden usar como una "librería" (conjunto de
             funcionalidades agrupadas bajo una clase), como sucede con clases bases en Java. Una clase String en
             Java tendrá todo un conjunto de métodos que no necesariamente se aplican solo a una instancia, y que
             pueden invocarse llamando a la clase y al método correspondiente.

             Imaginemos que queremos que PHP imite el comportamiento de Java, por lo tanto necesitaríamos
             crear clases base como Integer, String, Date, etc (que actualmente no existen), por lo que deberíamos
             buscar en el manual de PHP todas las funciones aisladas entre sí que tratan un mismo tema y agruparlos
             bajo la misma clase (espero que en algún futuro no muy lejano suceda en PHP). Así, con todas estas
             funcionalidades deberíamos poder aplicarlas tanto en una instancia o a través de una clase, para tener
             la libertad de no necesitar crear una instancia cada vez que queramos usar una funcionalidad que está
             aislada del contexto de la instancia.

             Por ejemplo, PHP tiene una función strtolower(), si quisiéramos ordenarlo en un entorno 100%
             Orientado a Objetos, podríamos decir que debería ser un método de una clase String, y deberíamos
             poder usarlo en cualquier ambiente, tanto bajo una instancia como sin ella. Si creamos un método
             común, solo lo podremos usar con una instancia:




             Bien podríamos cambiar el diseño y decir que no necesitamos crear constantemente una instancia que
             luego no se va a usar, por lo tanto cambiemos el método a "de clase".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                   SURFORCE / FORMACIÓN
285 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                               www.surforce.com




             De ahora en más podremos usarla de dos formas.

             Hay que tener en cuenta que si llamamos al método internamente, debemos cambiar el $this que se
             aplica a instancias por el método self que se aplica a elementos de clase.




             Otro ejemplo de uso muy tradicional es la típica clase Index, donde no necesariamente requiere que
             creemos una instancia, ya que solo la usaremos para iniciar la ejecución de un sistema, por lo que
             acceder a un método es suficiente.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
286 de 294        Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             12. Clases Abstractas

             "abstract" es una forma de decir que una clase "no se puede instanciar".

             Por ejemplo, si tenemos una clase que es demasiado "genérica" para realmente necesitar que se
             instancie, la aseguramos colocando un "abstract", por lo tanto solo servirá como "modelo" para poder
             hacer "herencia".

             Ej, la clase Persona, en la vida real es muy poco probable que necesitemos instanciarla, pero si
             contamos con clases de tipo Usuario que heredan características de Persona, sí les servirá de modelo.

             El otro caso, es la clase Index, que no se ejecuta como una instancia, lo hace como una clase, por lo
             tanto para hacer más robusto el diseño le agregamos "abstract" para que nadie la use de otra forma.

             abstract class MyBaseClass




             13. Métodos abstractos
             Un método abstracto obliga a una clase que hereda de la clase que lo contiene (al método abstracto) a
             definir el contenido de ese método. Una clase que tiene métodos abstractos debe definirse como clase
             abstracta. De la misma forma que podemos decir que una clase abstracta puede ser usada como una
             clase "modelo" para que otra herede de ella, podemos decir que un método abstracto sirve de modelo
             para que una clase que herede tenga que implementar el método definido en la clase padre.

             abstract class MyBaseClass

             {
                    abstract function display();
             }



                 ¿clases abstractas == interfaces?

                 Si hemos prestado atención, con las clases y métodos abstractos podemos "simular" el
                 comportamiento de las interfaces, al crear un "contrato de implementación". Pero no son lo mismo,
                 recordar que la herencia agrupa "elementos del mismo tipo / relación de parentesco" y las interfaces
                 "elementos que hacen lo mismo sin importar si tienen o no relación de parentesco"




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
287 de 294       Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             14. Validación de Tipo a través de Clases ( type hints)
             PHP desde sus orígenes es un lenguaje "dinámicamente tipado", lo que hace que cada variable defina su
             tipo según el valor que se le asigne, pero en sí no necesitamos como Java que es obligatorio definir el
             tipo antes de usarlo. Con el tiempo nos dimos cuenta que "tanta libertad" (no manejar tipos) puede no
             ser tan buena idea, por lo que ahora en más se habilita para los objetos la posibilidad de verificar "el
             tipo" del parámetro que estamos recibiendo, permitiendo con esto hacer diseños más robustos donde
             "no todo es tan dinámico", ya que ahora podemos aplicar un poco más de control. Si no se cumple con el
             tipo especificado, dará un error.

             function expectsMyClass(MyClass $obj) {

             }


             Un detalle importante a tener en cuenta es que la validación es "mecánica", es decir, cuando recibe el
             objeto pregunta cual es su tipo (con qué clase se creó o cuales son sus padres) y luego comparará
             exactamente con la cadena de texto que agregamos a la izquierda (en este caso MyClass).

             De aquí se desprenden dos cosas:

                 1. No es técnicamente necesario incluir la clase de filtro, por ejemplo, para usar el filtro MyClass
                    no hace falta hacer un require_once de MyClass, ya que con el nombre solo ya le alcanza para
                    hacer la comprobación.

                 2. Cuando se hereda, una clase es del tipo base (su clase) y la de su padre, por lo tanto si soy un
                    Usuario y además heredé de Persona, la validación puede ser filtro(Persona $persona) y ambas
                    serán aceptadas, porque ambos objetos son "personas".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
288 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             15.Soporte a invocaciones anidadas de objetos retornados

             En PHP4 estábamos obligados a hacer lo siguiente:

             $dummy = $obj->method();
             $dummy->method2();



             Ahora en PHP 5 podemos hacer las invocaciones en cadena de la siguiente forma:

             $obj->method()->method2();

             Es una técnica muy utilizada y se le llama "Interfaces fluidas" (fluent interface), y para aplicarlas
             deberíamos, a cada método que queremos que se pueda anidar con la ejecución de otro, hacer que
             retorne la instancia actual con "this". De esta forma podemos anidarlos, ya que la salida de uno es la
             misma instancia que se va a aplicar en siguiente método.




                                                                             Retorno la misma instancia del
                                                                             objeto donde estoy parado dentro
                                                                             de un método que normalmente no
                                                                             retornaría nada.



                                                                                  Idem.



                                                                              Métodos anidados, siempre
                                                                              aplicados a la instancia "usuario".




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                     SURFORCE / FORMACIÓN
289 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                 www.surforce.com




                 ¡No abuses de las interfaces fluidas!

                 Aunque esta técnica de simplificación es muy usada (Java, frameworks de javascripts y PHP, etc) y
                 puede sernos de utilidad, el abuso de este tipo de codificación puede "oscurecer" el entendimiento
                 del código, ya que si anidamos 10 métodos en una sola línea, al final, no sabremos qué hace.

                 Sugerencias: implemerlo en métodos simples, donde antes no retornaban nada, aprovecha y retorna
                 un this y solo lo usas cuando realmente lo necesites y veas que simplifique. En lo posible anida
                 siempre el mismo objeto. No pases de 3 o 4 anidaciones por línea, y trata de usarlo en lugares
                 puntuales, no hagas un sistema que predomine esta codificación o estarás condenado a pasar el
                 resto de tu vida en el infierno de los programadores! (según me han comentado, te tienen 24 hs al
                 día programando POO con COBOL )




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
290 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             16. Iteradores
             PHP5 permite ahora que las colecciones de una clase puedan ser iteradas a través de la misma clase con
             solo cumplir con una interface, así, con un simple foreach podremos recorrer los valores de un objeto:




             No es algo que necesitemos hacer regularmente, pero es importante saber que si nuestra clase solo
             esconde una colección, tal vez esta sea una forma más simple de acceder a la misma, o al revés, darle a
             una colección de objetos más funcionalidad que un simple array (observar que la interfaz define muchos
             comportamientos).




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                       SURFORCE / FORMACIÓN
291 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                   www.surforce.com



             17. __autoload()
             Es muy común que debamos incluir al principio de nuestra clase toda una serie de require_once de
             clases que necesitamos para trabajar. PHP5 ahora incorpora una función que permite definir un simple
             algoritmo de búsqueda de clases que se ejecutará siempre que nuestro fuente intente hacer un "new"
             de una clase (automáticamente la función recibirá por parámetros el nombre de la clase que intentamos
             instanciar, el resto lo definimos nosotros).

             function __autoload($class_name) {
                 require_once($class_name . "php");
             }

             $obj = new MyClass1();
             $obj2 = new MyClass2();




              No siempre es tan útil como parece

              Aunque a veces hacer "todo dinámico" no siempre es bueno, menos para la auto-documentación del
              código (ya que es útil saber claramente que tiene que requerir nuestra clase), cuando las estructuras
              de directorios son complicadas, esta función puede no sernos útil, o hasta generar una pequeña
              "sobrecarga" si por cada vez que intenta encontrar una clase tiene que buscarla de forma recursiva
              dentro del directorio de nuestra aplicación.

              Para usar, pero en situaciones concretas y muy simples.




             Nota final del Anexo
             En sucesivas versiones se irá ampliando esta sección con más comentarios sobre las nuevas
             características de PHP5 como lenguaje POO.




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Anexo II: Recopilación de                    “Hacer un programa a partir de unas
FRASES                                       especificaciones y caminar sobre el agua
"Los programas deben ser escritos para que   son cosas muy simples, siempre y cuando
la gente los lea (entienda) y solo           ambas estén congeladas.”
incidentalmente para que los ejecuten las
maquinas"
                                             "una de cada 10 personas nace con un
Abelson / Sussman                            talento innato para programar, para
                                             entenderse con las computadoras de una
                                             manera mágica e increíble....
Si hubiese preguntado a la gente qué es lo   lamentablemente los otros nueve creen
que quería me habrían respondido que         tener ese talento y por eso tenemos
caballos más rápidos - Henry Ford            carreras de ingeniería de software y libros
                                             como este"
(se puede aplicar cuando decimos “y por
qué no le preguntamos al usuario             "Un sistema exitoso se mide por su cantidad
exactamente qué quiere?”)                    de usuarios, no por su supuesta calidad"

                                             "Si quieres ganar dinero programando, solo
                                             escucha a alguien desesperado con un gran
"Pregunta: ¿Cómo se atrasa un año un
                                             problema, necesitado por una solución y
proyecto grande de software? Respuesta:
                                             con dinero"
Un día a la vez."
                                             "Si quieres ser pobre programando,
Fred Brooks
                                             escucha a todos los que te pidan un
                                             PEQUEÑO PROGRAMITA, que es MUY FACIL
                                             de hacer"

                                             "La historia de la programación es una
                                             carrera constante hacia mayores niveles de
                                             abstracción"
Programación Orientada a Objetos en PHP5                                         SURFORCE / FORMACIÓN
293 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                      www.surforce.com



             "La programación puede ser divertida, al                   "Si automatizas un procedimiento
             igual que la criptografía; sin embargo,                    desastroso, obtienes un procedimiento
             ambas no deberían combinarse"                              desastroso automatizado"
                                                                           -- Rod Michael
             "El software es como la entropía: difícil de
             atrapar, no pesa, y cumple la Segunda Ley                  A lo cual yo diría dado el fanatismo de los
             de la Termodinámica, es decir, tiende a                    programadores novatos por priorizar
             incrementarse"                                             “optimización de código” a funcionalidad de
                -- Norman Augustine                                     código

             "La imaginación es más importante que el                   "Si optimizas un procedimiento desastroso,
             conocimiento. El conocimiento es limitado,                 obtienes un procedimiento desastroso
             mientras que la imaginación no"                            optimizado"
                -- Albert Einstein                                         -- Rod Michael

             "Una de las cosas más fascinantes de los                   "Ley de Alzheimer de la programación: si
             programadores es que no puedes saber si                    lees un código que escribiste hace más de
             están trabajando o no sólo con mirarlos. A                 dos semanas es como si lo vieras por
             menudo están sentados aparentemente                        primera vez"
             tomando café, chismorreando o mirando a                       -- Via Dan Hurvitz
             las nubes. Sin embargo, es posible que
                                                                        "La simplicidad llevada al extremo se
             estén poniendo en orden todas las ideas
                                                                        convierte en elegancia"
             individuales y sin relación que pululan por
                                                                           -- Jon Franklin
             su mente"
                -- Charles M. Strauss

             "Comentar el código es como limpiar el
             cuarto de baño; nadie quiere hacerlo, pero
             el resultado es siempre una experiencia más
             agradable para uno mismo y sus invitados"
                 -- Ryan Campbell

             "Está bien investigar y resolver misteriosos
             asesinatos, pero no deberías necesitar
             hacerlo con el código. Simplemente
             deberías poder leerlo"
                -- Steve McConnell




             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/
Programación Orientada a Objetos en PHP5                                           SURFORCE / FORMACIÓN
294 de 294      Edición: Julio 2009 / Usuario: Juan Zapata                                                    www.surforce.com



             "Todo el mundo sabe el peligro de la                       desarrollo"
             optimización prematura. Pienso que                         -- Tom Cargill
             deberíamos estar igualmente preocupados
                                                                        "Depurar es al menos dos veces más duro
             con el diseño prematuro, es decir, el hecho
                                                                        que escribir el código por primera vez. Por
             de diseñar demasiado pronto lo que un
                                                                        tanto, si tu escribes el código de la forma
             programa debería hacer"
                                                                        más inteligente posible no serás, por
                -- Paul Graham
                                                                        definición, lo suficientemente inteligente
             (haciendo referencia al desarrollo evolutivo)              para depurarlo"
                                                                        -- Brian Kernighan
             "Por norma, los sistemas software no
             funcionan bien hasta que han sido
             utilizados y han fallado repetidamente en
                                                                        Fuente:
             entornos reales"
                -- Dave Parnas                                                101 citas célebres del mundo de la

             "Cuando se está depurando, el                                     informática
             programador novato introduce código
             correctivo; el experto elimina el código                         Otras 101 citas célebres del mundo
             defectuoso"
                -- Richard Pattis                                              de la informática

             "La mayoría de ustedes están familiarizados
             con las virtudes del programador. Son tres,
             por supuesto: pereza, impaciencia y orgullo
             desmedido"
             -- Larry Wall

             "El buen código es su mejor
             documentación"
             -- Steve McConnell

             "Cualquier código tuyo que no hayas
             mirado en los últimos seis meses o más es
             como si lo hubiese escrito otro"
             -- Eagleson's Law

             "El primer 90% del código corresponde al
             primer 90% del tiempo de desarrollo. El
             10% restante corresponde al otro 90% del



             SURFORCE | mail: info@surforce.com | web: http://www.surforce.com
             Licencia: http://creativecommons.org/licenses/by-nc/3.0/

Más contenido relacionado

PDF
Oopphp5
PDF
Oopphp5
PPTX
Tutorial del uso correcto de la rúbrica TIGRE en foros
PDF
Rúbrica y criterios TIGRE
PPSX
Rubrica Tigre - Grupo Tutoriando para el foro
PDF
SCJP, Clase 8: Inner Classes
PDF
SCJP, Clase 6: Collections
Oopphp5
Oopphp5
Tutorial del uso correcto de la rúbrica TIGRE en foros
Rúbrica y criterios TIGRE
Rubrica Tigre - Grupo Tutoriando para el foro
SCJP, Clase 8: Inner Classes
SCJP, Clase 6: Collections

Destacado (20)

PDF
SCJP, Clase 5: Control de Flujo
PPTX
PDF
SCJP, Clase 3: Asignaciones
PDF
SCJP, Clase 4: Operadores
PDF
SCJP, Clase 7: Generics
PPT
1 1 2 Datos Primitivas Y Objetos
 
PDF
SCJP, Clase 9: Threads
PDF
SCJP, Clase 10: Strings, I/O
PDF
Poo y mvc en php
PDF
Introducción a la Programación Orientada a Objetos
PDF
SCJP, Clase 2: Ejemplos De Enum, Poo
PPTX
Tipos de variables que Java maneja
ODP
Iniciación PHP 5. Programación Orientada a Objetos
PDF
SCJP, Clase 1: Introducción al curso, Intro a Java, Declaración y Control de ...
PPT
Curso Java Inicial 7 Excepciones
PPT
Curso Java Inicial 6 Polimorfismo, AbstraccióN E Interfaces
PPT
Curso Java Inicial 1 POO
PPTX
programacion orientada a objetos
PPT
Curso Java Inicial 2 - Introducción y Sintaxis
PPT
POO: Herencia, Abstraccion y Polimorfismo
SCJP, Clase 5: Control de Flujo
SCJP, Clase 3: Asignaciones
SCJP, Clase 4: Operadores
SCJP, Clase 7: Generics
1 1 2 Datos Primitivas Y Objetos
 
SCJP, Clase 9: Threads
SCJP, Clase 10: Strings, I/O
Poo y mvc en php
Introducción a la Programación Orientada a Objetos
SCJP, Clase 2: Ejemplos De Enum, Poo
Tipos de variables que Java maneja
Iniciación PHP 5. Programación Orientada a Objetos
SCJP, Clase 1: Introducción al curso, Intro a Java, Declaración y Control de ...
Curso Java Inicial 7 Excepciones
Curso Java Inicial 6 Polimorfismo, AbstraccióN E Interfaces
Curso Java Inicial 1 POO
programacion orientada a objetos
Curso Java Inicial 2 - Introducción y Sintaxis
POO: Herencia, Abstraccion y Polimorfismo
Publicidad

Similar a Programación orientada a objetos para php5 (20)

PDF
Php orientado a objetos
PDF
Programación orientada a objetos para php5
PDF
Clases de apoyo
PDF
Curso dreamweaver CS4
PDF
Enredando en la Universidad: web 2.0, redes sociales y otras herramientas
PDF
Inventando la Universidad 2.0. Educación 2.0 y eLearning 2.0
PDF
Unlicensed 7
PPTX
Tecnologia web 2
PPSX
Present mod-v-act-cierre
PDF
Palacios Alejandro Suites OnLine
PDF
Redes sociales y_comunidades_virtuales[2]
PDF
Curso CódigoK Back End (PHP + Laravel)
PPSX
Present mod-v-act-cierre
PPSX
Present mod-v-act-cierre
KEY
Aprenda y certifiquese en Spring
PPTX
Web 2.0 DIAPOSITIVAS
PPTX
Beneficios de la Web 2.0 en educacion
PPTX
Funciones php
PPTX
Web2.0
PPTX
Presentacion induccion web 2.0
Php orientado a objetos
Programación orientada a objetos para php5
Clases de apoyo
Curso dreamweaver CS4
Enredando en la Universidad: web 2.0, redes sociales y otras herramientas
Inventando la Universidad 2.0. Educación 2.0 y eLearning 2.0
Unlicensed 7
Tecnologia web 2
Present mod-v-act-cierre
Palacios Alejandro Suites OnLine
Redes sociales y_comunidades_virtuales[2]
Curso CódigoK Back End (PHP + Laravel)
Present mod-v-act-cierre
Present mod-v-act-cierre
Aprenda y certifiquese en Spring
Web 2.0 DIAPOSITIVAS
Beneficios de la Web 2.0 en educacion
Funciones php
Web2.0
Presentacion induccion web 2.0
Publicidad

Programación orientada a objetos para php5

  • 1. Julio 2009 / Versión 1.8.9 PROGRAMACIÓN ORIENTADA A OBJETOS PARA PHP5 "Aprende de forma simple y definitiva POO para PHP5, deja de ser Programador de Páginas Dinámicas y empieza a convertirte en Desarrollador de Sistemas" por Enrique Place Usuario: Juan Zapata
  • 2. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 2 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 3. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 3 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/ SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 4. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 4 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Este LIBro es un Servicio” Este Libro está licenciado bajo Creative Commons y puedes distribuirlo con libertad a quienes consideres que pueda serle útil tenerlo. Si adquirir el SERVICIO COMPLETO podrás tener decides acceso a usuarios.sURFORCE.com y por el período de tiempo que elijas obtendrás: 1. Poder hacer CONSULTAS DIRECTAS AL AUTOR: cualquier parte del libro, tanto dudas sobre ejemplos, capítulos, ejercicios y estas se responderán normalmente durante las próximas 24-48hs (aunque lo más probable que obtengas una respuesta en pocas horas). 2. Acceso a TODOS LOS FUENTES: de todos los ejercicios del libro, revisados y comentados por el mismo autor. 3. ACTUALIZACIONES mensuales: tanto correcciones como ejemplos o hasta capítulos nuevos, lo que podrá incluir a futuro acceso a material multimedia (screencasts, podcasts, etc). 4. Cambia el contenido del libro: si consideras que algún capítulo, ejemplo o ejercicio podría mejorarse, o algún tema que ves no se encuentra tratado en el libro, tu sugerencia será recibida y tenida en cuenta para la próxima actualización mensual del libro. Aprovecha la oportunidad de expandir las posibilidades de un libro digital obteniendo todo el soporte que no te podría dar nunca un libro tradicional (y de paso salvamos algunos bosques). ADQUIERE EL LIBRO COMPLETO en SURFORCE y accede a todos los servicios en http:/usuarios.surforce.com [ATENCIÓN: si este material se encuentra impreso, es probable que ya esté desactualizado] SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 5. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 5 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Versiones del documento Versión Fecha Descripción Autor 1 1/01/2009 Primera versión enriqueplace 1.1 15/01/2009 Segunda revisión, recopilación de ejemplos enriqueplace 1.2 31/01/2009 15 días de revisión de contenidos enriqueplace 1.3 01/02/2009 Se separa como un capítulo el tema enriqueplace “Paquetes UML” y se agrega un capítulo nuevo sobre “Excepciones” 1.4 3/02/2009 Agrega capítulo “Debemos enriqueplace Profesionalizarnos” (post del blog) 1.5 4/02/2009 Error: corrección capítulo 8, diseño 2, cambia andresfguzman echo por retorno en clase Persona (corrector) 1.6 6/2/2009 Agrega nota de autor recalcando el tema de enriqueplace los estándares de codificación definidos por Zend y que todos los ejemplos de este libro lo seguirán 1.7 6/2/2009 Enumera los Principios que deberíamos seguir enriqueplace los desarrolladores 1.7.1 10/2/2009 Correcciones en fuentes, espacios, estética Dennis Tobar (lector) 1.7.2 28/2/2009 Cap.11: Agrega explicación sobre auto- Colabora: relación con Persona (cuadro de color verde) Antonio L. Gil (lector) 1.7.3 10/3/2009 Cap. 10: Agrega ejemplo y explicación extra Colabora: en el caso de "qué hacer con las relaciones cíclicas / bidireccionales" Eduardo de la Torre (lector) 1.7.4 22/3/2009 Cap. 14: corrección en la redacción del Colabora: resumen final Raquel Diaz (lector) 1.7.5 24/3/2009 Cap.11: Agrega explicación de "Confusión enriqueplace común" con respecto a confundir bidireccional con cíclica (cuadro "verde") SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 6. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 6 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 1.7.6 26/3/2009 Cap.7: el ejemplo de calcular la edad no está Colabora: completo, debería retornar un integer y no el valor del atributo "_fechaNacimiento" Carlos Arias (lector) 1.7.7 26/3/2009 Cap.10: amplía la explicación sobre Colabora: “Multiplicidad” Christian Tipantuña (alumno) 1.7.8 1/4/2009 Cap. 7: ejemplo “decirEdad” tiene un Colabora: parámetro de más Carlos Arias (alumno/lector) 1.8.0 3/4/2009 Agrega Anexo: "Qué es lo nuevo en PHP5?", enriqueplace basado en el artículo "What's New in PHP5?" 1.8.1 25/4/2009 Cap.19, parte 2, error, cambia "Copy" por Colabora: "MaquinaDeEscribir" Karina Diaz (alumna/lector) 1.8.2 25/4/2009 Cap.19, ajusta diagrama UML, cambia Colabora: parámetro leer:String por texto:String en MaquinaDeEscribir Karina Diaz (alumna/lector) 1.8.3 15/5/2009 Revisión Cap.1 enriqueplace 1.8.4 20/5/2009 Revisión Cap.2 enriqueplace 1.8.5 4/7/2009 Revisión Cap.3, definición de “contexto” enriqueplace 1.8.6 4/7/2009 Capítulo 3 está repetido, dos capítulos tienen enriqueplace el mismo nombre, se unifican en el capítulo 4, cambiando al nombre de “POO según los Manuales” (incluyendo ahora Wikipedia y el manual Oficial) 1.8.7 4/7/2009 Cap.4 agrega enlaces a Wikipedia enriqueplace 1.8.8 5/7/2009 Cap.5 – revisión y ampliación sobre el enriqueplace concepto de “diseño” SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 7. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 7 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 1.8.9 5/7/2009 Cap.6 – revisión enriqueplace ¡Mis más sinceros agradecimientos a lectores y colegas con sus aportes! SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 8. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 8 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Sobre el Autor Enrique Place (35 años), nacido en Uruguay y actualmente viviendo en Argentina (pero “ciudadano de Internet”), es uno de los tantos “emprendedores por naturaleza” que cambió a los 14 años su fanatismo por las artes marciales (algunos llegaron a pensar que sería el sucesor sudamericano del Pequeño Dragón) por el fanatismo hacia la informática. Por cuestiones que solo el destino sabrá, tuvo la oportunidad de trabajar con los antiguos y míticos dinosaurios de la informática llamados Mainframes y participó en una misión para salvar a la raza humana de su extinción migrando aplicaciones para sobrevivir al colapso del Y2K, convirtiendo a diestra y siniestra código Mantis / Mainframe a Microfocus Cobol y Windows NT / Unix AIX. Paralelamente, fundó una pequeña empresa llamada LINUXTECH, quién fue la primer importadora para Uruguay de SuSE GNU/Linux (Alemania) y que dio los primeros pasos al evangelizar usuarios y empresas brindando servicios profesionales. De profesión “Analista Programador”, estudiante y posteriormente docente en la Universidad ORT (Uruguay), aprovechó todo lo que pudo aprender de arquitecturas como .Net y Java, conocer de Patrones de Diseño (GOF), como para darse cuenta que PHP, su verdadero amor informático, tenía un gran potencial por su simplicidad y pragmatismo, y que además su comunidad carecía completamente de una visión amplia como para entender todo lo que aún faltaba recorrer (como lo habían hecho ya otras tecnologías). Finalmente, el autor no se considera “gurú” y simplemente como “en el país de los ciegos, el tuerto es rey”, de la mano a su facilidad para enseñar (radicada en que aún es “alumno de todo”), es que se inicia en el camino de tratar de transmitir nuevos conocimientos a la Comunidad PHP. Este libro se escribe con el objetivo de que los actuales Programadores PHP se conviertan en el corto plazo en Desarrolladores PHP aprobando la materia que más les cuesta: "Programación Orientada a Objetos en PHP5" "Este libro fue escrito para ti, Pequeño Saltamontes" SURFORCE | mail: info@surforce.com | blog: http://www.surforce.com/blog/| web: surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 9. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 9 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Agradecimientos A mi familia: mi amada esposa Laura, mis amadas hijas Micaela y Martina, que tantas veces soportaron que su padre estuviera ausente por tener la cabeza en otro lado. Este fue uno de los tantos proyectos que le robó tiempo a la familia, pero que espero que de alguna forma u otra lo disfruten ellas. A la Universidad ORT Uruguay, gracias a los buenos docentes (también se aprende de los malos) que me tocaron en mi carrera y que me ayudaron a tener los conocimientos suficientes como para poder trabajar con PHP “de otra forma”. Carlos Cantonnet, docente en Análisis y Diseño Orientado a Objetos y cumpliendo el rol de "Arquitecto de Sistemas" en multinacionales como TATA TCS, sus excelentes clases lograron abrir mi mente con sus explicaciones simples, directas, y con mucho humor. Ahí empecé a conocer de Patrones de Diseño y la magia de los Principios de Diseño Orientado a Objetos. Nicolás Fornaro, docente en Programación Java y Análisis y Diseño, por sus muy buenas clases que, a diferencia de Cantonnet, me permitían tener una visión menos teórica y mucho más práctica de los Objetos y los Patrones de Diseño. A muchos colegas y amigos que de alguna forma u otra siempre apoyaron o inspiraron mis locuras, pero principalmente cuando alguna vez me dijeron frases como “eso no se puede”, “no vale la pena el esfuerzo”, “no le veo sentido”, “no vas a poder con todo”. Me quedo con la frase “No sabían que era imposible, por eso lo lograron” Sin ustedes no lo hubiera logrado ¡GRACIAS A TODOS! SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 10. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 10 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Revisores de este libro” Amigos y colegas que ayudarán con la revisión en busca de errores y/o sugerencias. Como es un libro que se irá actualizando mensualmente todas sus mejoras se podrán apreciar a finales de febrero 2009 (de todas formas creo que mi orgullo me impedirá hacerles caso ;-)). Andrés Guzmán, blogger colega de PHP y Zend Chile http://bolsadeideas.cl/zsamer/ Christian Serrón, uno de mis mejores alumnos Uruguay http://serron.surforce.com Christopher Valderrama , colega de PHP y Zend, Moderador en Foros del Web / Sección POO – PHP México http://web2development.blogspot.com/ SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 11. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 11 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Prólogo Estimados Lectores Tradicionalmente se dice que el alumno en artes marciales busca toda su vida el maestro perfecto cuando en realidad con los años y habiendo acumulado experiencia se da cuenta que siempre estuvo dentro suyo. Una de las principales razones de escribir este libro fue no haber encontrado un libro similar para poder leer y consultar. A su vez estoy convencido que se pueden escribir libros “pragmáticos”, “simples” y “directos”, evitando entrar en disertaciones complejas de “docente que no baja al nivel del alumno que no domina el tema a tratar”. El libro es el resultado de apuntes de estudios, investigaciones, experiencia personal, y materiales que fueron desarrollados para el primer taller de POO para PHP5 (edición 2008), por eso verás ejercicios, soluciones y comentarios de los errores que estadísticamente son muy probables que cometas durante el aprendizaje. Me tomé el trabajo de revisar todos los capítulos, generar nuevos y a su vez actualizar explicaciones que fueron vertidas en los foros (la discusión con los alumnos enriqueció los ejemplos y debían quedar registrados de forma permanente). Para no ser menos, acostumbrado a intentar “un paso más allá”, este libro no será comercializado solo como un archivo “pdf”, la idea es ofrecer un servicio completo e intentar asegurar al lector el máximo de valor agregado que en este momento puedo concebir. Traté de hacer el libro que yo compraría, espero satisfacer tus expectativas, y si no lo logro, aún estás a tiempo de que lo solucione, ya que el libro “está vivo” y todas las sugerencias generarán nuevas actualizaciones. Saludos! Enrique Place enriqueplace@gmail.com Blog Personal http://enriqueplace.blogspot.com Blog Técnico http://phpsenior.blogspot.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 12. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 12 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Contenido Introducción: ............................................................................................................................................... 21 ”Los Desarrolladores PHP debemos Profesionalizarnos” ........................................................................... 21 Esta reflexión se la escribo a todos los "Programadores PHP" ............................................................... 21 Enfrentar la realidad con madurez ......................................................................................................... 21 Mi experiencia personal.......................................................................................................................... 22 La culpa es enteramente nuestra ........................................................................................................... 23 Debemos pasar de los dichos a los hechos ............................................................................................. 24 Capitulo 1 - "Nuestros Principios como Desarrolladores" .......................................................................... 25 Principio 1: RTFM - "Lee el Maldito Manual".......................................................................................... 27 Principio 2: DRY - "No Te Repitas" .......................................................................................................... 27 Principio 3: KISS - "Mantenlo Simple, Estúpido!" ................................................................................... 27 Principio 4: Estándar de Codificación PHP / Zend................................................................................... 27 Capitulo 2 - “Introducción a los Objetos” ................................................................................................... 29 “Vacuidad: vaciar todos los conocimientos” .......................................................................................... 31 “La sencillez es la mejor arquitectura “ .................................................................................................. 31 “Lo más importante es detectar los objetos” ......................................................................................... 32 En resumen ............................................................................................................................................. 32 Capítulo 3 - “Cómo Pensar en Objetos” ...................................................................................................... 34 “Lo menos importante es el código” ...................................................................................................... 36 “Un niño pequeño” ................................................................................................................................. 36 “El medio de comunicación” ................................................................................................................... 37 Capítulo 4 - “POO según LOS MANUALES” ................................................................................................. 38 “La POO según Wikipedia” ...................................................................................................................... 39 “POO según el manual Oficial de PHP” ................................................................................................... 42 Capítulo 5 - “Empezar a plasmar los objetos en un diseNo” ...................................................................... 44 “Cómo representar la estructura de los objetos” .................................................................................. 46 En Resumen ............................................................................................................................................ 51 Capítulo 6 - “Introducción a UML” .............................................................................................................. 53 “UML, el medio y no el fin en sí mismo”................................................................................................. 55 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 13. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 13 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “UML y el público objetivo” .................................................................................................................... 55 “UML es independiente del lenguaje” .................................................................................................... 56 En resumen ............................................................................................................................................. 57 Capítulo 7 - “Cómo representar una clase en UML” ................................................................................... 58 “Conceptos Generales” ........................................................................................................................... 60 Mi primer diagrama UML........................................................................................................................ 60 Cómo se traduce en código .................................................................................................................... 62 Sección #1 – nombre de la clase ......................................................................................................... 62 Sección #2 – los atributos de la clase.................................................................................................. 62 Sección #3 – los métodos de la clase .................................................................................................. 64 “El Constructor” ...................................................................................................................................... 64 Probando el objeto en un contexto determinado .................................................................................. 66 En Resumen ............................................................................................................................................ 67 Capítulo 8 - Ejercicio "Micaela y el Perro" .................................................................................................. 68 Requerimientos....................................................................................................................................... 70 Solución ................................................................................................................................................... 71 Aplicación del “Principio KISS” ................................................................................................................ 72 Sugerencias para enfrentar los diseños .................................................................................................. 72 Propuesta de Diseño 1 ............................................................................................................................ 73 Diagrama UML .................................................................................................................................... 73 Traducción de UML a PHP ................................................................................................................... 74 Propuesta de Diseño 2 ............................................................................................................................ 76 Cambios............................................................................................................................................... 76 Diagrama UML .................................................................................................................................... 76 Traducción UML a PHP ........................................................................................................................ 77 En Resumen ............................................................................................................................................ 79 Capítulo 9 - Los métodos "getter / setter" o "accesores / modificadores" ................................................ 80 Requerimiento 1 ..................................................................................................................................... 84 Requerimiento 4 .................................................................................................................................... 85 En Resumen ............................................................................................................................................ 88 Capítulo 10 - “Cómo representar las Relaciones entre clases en UML” ..................................................... 89 La Relación de Dependencia ................................................................................................................... 91 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 14. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 14 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Representación UML........................................................................................................................... 91 Cómo se traduce a código ................................................................................................................... 92 Caso 1 – instancio un objeto B dentro de un método de A .................................................................... 92 Caso 2 – recibo por parámetro de un método de A un objeto B............................................................ 93 La Relación de Asociación ....................................................................................................................... 94 Representación UML........................................................................................................................... 94 UML del ejemplo del Auto ...................................................................................................................... 96 Variaciones de Asociación: Relación de Agregación y Relación de Composición ................................... 97 Relación de Agregación ....................................................................................................................... 97 Relación de Composición .................................................................................................................... 97 Ejemplos de Agregación y de Composición ........................................................................................ 97 ¿Qué relaciones se deberían evitar?....................................................................................................... 99 Ejemplo de relación cíclica .................................................................................................................. 99 Resumiendo rápidamente algunos conceptos complementarios ........................................................ 101 “Navegabilidad” ................................................................................................................................ 101 “Definición de Roles” ........................................................................................................................ 101 Resumen ............................................................................................................................................... 102 Capítulo 11 - Ejercicio "Micaela, el Perro y la Escuela” ............................................................................ 103 Requerimientos..................................................................................................................................... 105 Solución ................................................................................................................................................. 106 “Errores Comunes” ............................................................................................................................... 107 Detalle importante a tener en cuenta con las relaciones ..................................................................... 111 El método público toString() ................................................................................................................. 113 Lo que dice el manual de toString() ..................................................................................................... 115 Agregando las relaciones que se ven desde Index ............................................................................... 116 Crear la clase Index a partir de la representación UML ........................................................................ 117 Segunda propuesta de diseño .............................................................................................................. 118 Diagrama UML .................................................................................................................................. 119 En Resumen .......................................................................................................................................... 120 Capítulo 12 - Ejercicio "La Escuela y los coches escolares"....................................................................... 121 Requerimientos..................................................................................................................................... 122 Guía ....................................................................................................................................................... 122 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 15. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 15 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución ................................................................................................................................................. 123 “Errores Habituales” ............................................................................................................................ 123 “Comentarios Generales” ..................................................................................................................... 125 Navegabilidad ....................................................................................................................................... 126 Cómo deberían ser las búsquedas ........................................................................................................ 127 Diagrama UML ...................................................................................................................................... 128 Resumen ............................................................................................................................................... 129 Capítulo 13 - Ejercicio “Implementar diagrama de diseNo UML” ............................................................ 130 Requerimientos..................................................................................................................................... 131 Solución ................................................................................................................................................. 132 ¿Qué sucedería si se están usando mal las relaciones? ....................................................................... 133 Comentarios adicionales ....................................................................................................................... 134 Errores habituales ................................................................................................................................. 135 Consejos ................................................................................................................................................ 136 Diagrama UML ...................................................................................................................................... 137 Ejemplo codificado ................................................................................................................................ 138 Resumen ............................................................................................................................................... 139 Capítulo 14 - Ejercicio “Sistema para empresa que realiza encuestas”.................................................... 140 Requerimientos..................................................................................................................................... 141 Solución ................................................................................................................................................. 142 Posibles dificultades .......................................................................................................................... 142 Requerimientos presentados ............................................................................................................ 142 Requerimientos Erróneos ................................................................................................................. 142 Muchos Diseños Posibles .................................................................................................................. 143 Paso 1 – “Crear las clases y atributos” .............................................................................................. 144 Paso 2 – “Relacionar las clases” ........................................................................................................ 145 “Receta de cocina” ................................................................................................................................ 149 “El código”............................................................................................................................................. 150 Index creado a “prueba y error” ........................................................................................................... 155 Resumen ............................................................................................................................................... 158 Capítulo 15 - “Herencia, Interfaces y Polimorfismo” ................................................................................ 159 La Herencia............................................................................................................................................ 161 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 16. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 16 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Representación UML............................................................................................................................. 162 Cómo se traduce a código..................................................................................................................... 163 Caso 1 –Usuario hereda de Persona ..................................................................................................... 164 Caso 2 –Persona agrega un constructor ............................................................................................... 166 Caso 3 –Persona agrega su toString...................................................................................................... 167 Caso 4 – Los usuarios necesitan un id y una fecha de ingreso ............................................................. 169 Caso 5 – Los usuarios necesitan un id único “autogenerado” .............................................................. 170 Explicación sobre la visibilidad de los atributos y métodos .................................................................. 173 “Visibilidad Pública” .......................................................................................................................... 173 “Visibilidad Privada”.......................................................................................................................... 173 “Visibilidad Protegida” ...................................................................................................................... 173 Caso 6 – Ejemplos varios ....................................................................................................................... 174 Clase abstracta .................................................................................................................................. 175 Herencia Múltiple ............................................................................................................................. 176 “Sobre-escritura” de métodos .......................................................................................................... 177 Evitar la herencia y la “sobre-escritura” de métodos ....................................................................... 178 “Generalización” versus “Especialización” ........................................................................................... 179 Entonces, ¿qué es Polimorfismo? ......................................................................................................... 180 La implementación............................................................................................................................ 181 “Diseño más robusto” ....................................................................................................................... 182 ¿La herencia está limitada? .................................................................................................................. 182 Las interfaces: “el poder desconocido” ................................................................................................ 184 Implementación ................................................................................................................................ 185 Cómo funciona .................................................................................................................................. 186 Detalles importantes......................................................................................................................... 186 Repaso de lo visto hasta el momento ................................................................................................... 187 Las interfaces son “contratos de implementación” .......................................................................... 188 Anexo ................................................................................................................................................ 188 Resumen ............................................................................................................................................... 189 Capítulo 16 - Ejercicio “Clase de Persistencia”......................................................................................... 190 Requerimientos..................................................................................................................................... 191 Solución ................................................................................................................................................. 193 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 17. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 17 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Primer escenario: “crear una conexión a la base de datos” ................................................................. 194 Segundo escenario: “crear una clase de persistencia” ......................................................................... 194 Tercer escenario: “abstraer el tipo de base de datos” ......................................................................... 194 Diseño UML ........................................................................................................................................... 195 Ejemplo codificado................................................................................................................................ 196 Principio de diseño “Abierto / Cerrado” ............................................................................................... 200 Resumen ............................................................................................................................................... 201 Capítulo 17 - Ejercicio “Librería y la búsqueda de Libros” ........................................................................ 202 Requerimientos..................................................................................................................................... 203 Solución ................................................................................................................................................. 204 Diseño “Borrador” (con partes incompletas) ....................................................................................... 205 Diseño “Final” cumpliendo con todos los requerimientos ................................................................... 206 Comentarios sobre el diseño ................................................................................................................ 208 Resumen ............................................................................................................................................... 214 Capítulo 18 - “Los Paquetes en UML” ....................................................................................................... 215 Cómo se representan ............................................................................................................................ 216 ¿Qué es una Arquitectura de 3 capas? ................................................................................................. 217 ¿Que son entonces los Namespaces? ................................................................................................... 218  PHP5: Diseño en 3 capas y problemas con subdirectorios ....................................................... 218  "Petición para soporte de Name Spaces en PHP5"................................................................... 218 En Resumen .......................................................................................................................................... 219 Capítulo 19 - Ejercicio “Programación ‘Orientada a la Implementación’ vs ‘Orientada a la Interface’" .. 220 Requerimientos..................................................................................................................................... 222 Solución ................................................................................................................................................. 224 Parte 1: hacer una “máquina de escribir” siguiendo el ejemplo del artículo ....................................... 225 Parte 2: Agregar interfaces al diseño propuesto en la parte 1 ............................................................. 229 Implementación .................................................................................................................................... 231 ¿Y el Diagrama de Paquetes? ............................................................................................................ 234 El “Principio de Inversión de dependencias (DIP)” ............................................................................... 235 Resumen ............................................................................................................................................... 237 Comentarios adicionales ....................................................................................................................... 238 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 18. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 18 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 20 - Ejercicio “Desarrollar un sistema de ABM de usuarios”...................................................... 239 Requerimientos..................................................................................................................................... 240 Solución ................................................................................................................................................. 243 Cambios que se aplicaron en la resolución........................................................................................... 244 Diagrama tradicional de paquetes ........................................................................................................ 245 Diagramas de clases y sus paquetes de origen ..................................................................................... 246 Diagramas de Secuencia ....................................................................................................................... 247 Partes esenciales del código de la solución .......................................................................................... 249 Resumen ............................................................................................................................................... 257 Capítulo 21 - Anexo: “Manejo de excepciones” ....................................................................................... 258 Introducción .......................................................................................................................................... 259 Básicamente cómo funcionan las excepciones ..................................................................................... 261 Estructura interna de una clase Exception ........................................................................................... 262 Importante: PHP no tiene excepciones por defecto ............................................................................. 264 ¿Cuan grave es no tener Excepciones predefinidas y por defecto? ................................................. 264 Ejemplo funcional de excepciones en PHP5 ......................................................................................... 265 Importante: el orden de las excepciones.............................................................................................. 266 Beneficios de las Excepciones ............................................................................................................... 267 En Resumen .......................................................................................................................................... 268 Capítulo 22 - Cierre del libro y reflexiones finales .................................................................................... 269 Anexo I: "Qué es lo nuevo en PHP5?" ....................................................................................................... 273 Características del Lenguaje ................................................................................................................. 274 1.Modificadores de acceso "public/private/protected" ....................................................................... 274 2. El método reservado __construct() .................................................................................................. 275 3. El método reservado __destructor()................................................................................................. 275 4. Interfaces .......................................................................................................................................... 276 5. El operador "instance of" .................................................................................................................. 277 6. Operador "final" para los métodos ................................................................................................... 277 7. Operador "final" para la clase ........................................................................................................... 278 8. Método reservado __clone para clonado de objetos ....................................................................... 279 9. Atributos Constantes para las clases ................................................................................................ 281 10. Miembros estáticos o de clase (static)............................................................................................ 282 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 19. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 19 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 11. Métodos estáticos o de clase (static) .............................................................................................. 284 12. Clases Abstractas ............................................................................................................................ 286 13. Métodos abstractos ........................................................................................................................ 286 14. Validación de Tipo a través de Clases ( type hints) ......................................................................... 287 15.Soporte a invocaciones anidadas de objetos retornados ................................................................ 288 16. Iteradores ........................................................................................................................................ 290 17. __autoload().................................................................................................................................... 291 Anexo II: Recopilación de FRASES ............................................................................................................. 292  101 citas célebres del mundo de la informática ....................................................................... 294  Otras 101 citas célebres del mundo de la informática ............................................................. 294 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 20. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 20 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Si adquieres el [libro + servicios] puedes hacer todas las consultas que necesites de forma directa al autor. Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 21. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 21 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Introducción: ”Los Desarrolladores PHP debemos Profesionalizarnos” Basado en el post: Los Desarrolladores PHP debemos profesionalizarnos o quedaremos descartados por obsoletos Esta reflexión se la escribo a todos los "Programadores PHP" Al día de hoy la mayoría de los institutos o universidades de muchos países siguen enseñando PHP4, o mejor dicho, programación "scripting" básica. Se mueven en el viejo concepto de la "programación estructurada", trabajando constantemente sobre código que mezcla html y sintaxis PHP, todo como si de una ensalada estuviéramos hablando. Casi paralelamente, los jóvenes autodidactas siguen por el mismo camino, tal vez ayudados por la gran cantidad de material repetido y obsoleto que se encuentra tanto en la web como en las editoriales de turno, donde a pesar que un libro haya sido impreso recientemente, los autores siguen siendo los mismos y escribiendo -una y otra vez- sobre los mismos temas elementales. Enfrentar la realidad con madurez Solo nos damos cuenta que estamos en un grave problema cuando nos enfrentamos a la realidad: salimos al mercado laboral y con inocente sorpresa vemos que se habla mayoritariamente de Java o .Net, de UML, desarrollos en 3 capas, lógica de negocios, persistencia, polimorfismo, frameworks, patrones de diseño, refactoring... y tú solo tienes una vaga idea de algunos conceptos, pero nulo conocimiento de si es realmente posible hacerlo con PHP... Diseño UML: Representación de Paquetes y sus relaciones ¿No crees que algo está pasando y que tú estás quedando fuera de la "conversación"? Este es el gran problema de la mayoría de los "Programadores PHP": se quedan en el "lenguaje", en la programación lisa y llana, rechazando todo lo que sea objetos hasta que no les queda otra salida que aprender a usarlos mínimamente... pues todas las nuevas herramientas solo hablan "ese" idioma. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 22. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 22 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Hasta donde piensas que podemos llegar con tan poca preparación? Mi experiencia personal De lo que trato de hablar en este blog es de "profesionalizarnos", de copiar y mejorar, de aprender y evolucionar. La mayoría de los temas que expongo no son nuevos, trato de basarme en autores reconocidos y darle más prioridad a los conceptos que al lenguaje, y por sobre todas las cosas: ser simple y directo (pragmático antes que dogmático, pero sin olvidarme de lo último). Hay muchas cosas que desconozco de PHP y otras que directamente no uso, y nunca me baso en la memoria, siempre voy a buscar hasta lo más elemental al manual (doy prioridad al razonamiento por sobre la retención mecánica de conocimientos). Siguiendo esta metodología, mañana deberías poder cambiar de lenguaje y seguir trabajando sin problemas, pues los conceptos base los tendrías claros y estos se aplican sin importar la plataforma que estés usando. Muchas veces comento que los temas sobre los que escribo son elementales para muchos desarrolladores Java de nivel medio y alto, pero en el ambiente PHP esto cambia (todavía no hemos madurado hacia el concepto de "arquitectura") donde "en el mundo de los ciegos puedo ser rey". Debemos cambiar la mentalidad ahora que existe PHP5 y que su nueva sintaxis nos permite hacer muchas cosas que son habituales en el mundo Java. "la vida es demasiado corta para Java", detrás de la remera dice "Usa PHP" (verídico) Por lo tanto, tenemos todas las herramientas para "evolucionar" y no quedarnos en las excusas. Programador versus Desarrollador Desarrollar Orientado a Objetos va más allá que crear objetos aislados que solo contienen datos, programar usando algunos objetos es distinto a desarrollar 100% Orientado a Objetos, ser programador es distinto a ser un desarrollador, un sitio web no es lo mismo que un sistema web. Existen, además de los objetos, "Principios de Diseño (OO)", "Patrones de Diseño (OO)", el lenguaje de diseño UML, frameworks, etc, y todo es perfectamente aplicable usando PHP. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 23. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 23 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Es más, muchos de estos conceptos e ideas son independientes al lenguaje si este cumple mínimamente con las características de la OO, cosa que sucede a partir de PHP5 en adelante y que PHP4 casi carece por completo. Finalmente, es mi visión que un programador resuelve problemas aislados usando un lenguaje, pero un desarrollador diseña e implementa una solución global, une los componentes en un único sistema integrado y es lo suficientemente inteligente y estratega para poder reutilizar la experiencia y conocimientos adquiridos en favor de Ejemplo de Patrón de Diseño: Template Method los próximos desarrollos. Los sistemas que van quedando atrás nunca serán un lastre porque podrán ser mantenidos con el mínimo costo posible, permitiendo que el desarrollador pueda afrontar nuevos y enriquecedores desafíos. Todos estos detalles los percibimos claramente cuando nuestros desarrollos dejan de ser un "programa menor" y necesitamos crecer, pero vemos que con los conocimientos que contamos hasta el momento todo se nos hace cuesta arriba. La culpa es enteramente nuestra No podemos quejarnos que a los programadores Java se les paga el doble que a nosotros y que a la mayoría de los proyectos PHP se los desvalorice, se los trate como "algo menor", "poco serio", todo porque es un "simple lenguaje web" limitado en sus posibilidades. El "Simple Lenguaje" lo hacemos todos, al ser "Simples Programadores PHP" y nuestras son las limitaciones fundamentales. Perfectamente podemos tratar de trabajar "más seriamente" como lo hacen los "desarrolladores Java", y tratando con creatividad de suplir las carencias momentáneas (como el muy sonado caso de la falta de "namespaces"). PHP se está orientando a convertir en una "arquitectura", a parecerse a un J2EE pero mucho más simple y directo. El proceso hace tiempo que inició. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 24. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 24 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Debemos pasar de los dichos a los hechos De la misma forma, creo que nos hace falta tener más "sentimiento de comunidad", como sucede habitualmente -hasta de forma exagerada- en el mundo GNU/Linux. No es posible que nos sigamos quejando que los proveedores de hosting siguen usando PHP4. Deberíamos hacer campañas para promover la migración a las nuevas versiones de PHP, pero fundamentalmente, incorporar en nuestros desarrollos las características avanzadas del lenguaje, e invitar a usarlo como si fuera una arquitectura, actualizar a nuestro equipo de desarrolladores, visitar empresas, universidades, etc. ¿Tú, qué vas a hacer? ¿Te vas a quedar donde estás o te vas a subir al tren? ¿Eres parte del problema o parte de la solución? Tenemos que especializarnos y profesionalizarnos, el mundo pide POO, arquitecturas, capas, etc, y habla en "UML"... tú, ¿en qué idioma hablas? Post Publicado el 30 de Abril 2006 SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 25. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 25 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capitulo 1 - "Nuestros Principios como Desarrolladores" Peor que usar un mal estándar o un estándar incorrecto es no seguir ninguno, de la misma forma, lo peor que podemos hacer es no tener ningún criterio para enfrentar los desarrollos. Para aumentar nuestra productividad, tanto individualmente como en equipo, debemos siempre seguir estándares y fijar criterios de desarrollo. Nuestro objetivo debería ser contar con una “plataforma de desarrollo” que nos evite tener que repensar problemas típicos y cotidianos, y concentrarnos solo en los problemas nuevos. Empecemos por el principio, por lo más básico y elemental… nuestros principios base. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 26. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 26 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Nadie debe empezar un proyecto grande. Empiezas con uno pequeño y trivial y nunca debes esperar que crezca; si lo haces solamente sobre-diseñarás y generalmente pensarás que es más importante de lo que lo es en esta etapa. O peor, puedes asustarte por el tamaño de lo que tu esperas que crezca. Así que empieza pequeño y piensa en los detalles. No pienses acerca de la foto grande y el diseño elegante. Si no resuelve una necesidad inmediata, seguramente está sobre-diseñado. Y no esperes que la gente salte a ayudarte, no es así como estas cosas funcionan. Primero debes tener algo medianamente usable y otros dirán "hey, esto casi funciona para mí" y se involucrarán en el proyecto." - Linus Torvalds SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 27. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 27 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Principio 1: RTFM - "Lee el Maldito Manual" RTFM es una sigla que significa “lee el maldito manual”, algo muy usado en los foros como respuesta hacia los novatos que lo último que hacen es leerlos (lamentablemente *todo* se encuentra ahí) http://es.wikipedia.org/wiki/RTFM Principio 2: DRY - "No Te Repitas" “No te repitas” significa algo muy simple: si cuando desarrollas ves que al programar “copias” un código para “pegarlo en otro lado”, es muy probable que estés haciendo algo mal, ya que ese código debería estar aislado y ser usado a través de parámetros. Generalmente no existe razón para tener que duplicar el código, si estamos muy apurados, seguro, lo pagaremos muy caro dentro de poco. http://es.wikipedia.org/wiki/DRY Principio 3: KISS - "Mantenlo Simple, Estúpido!" Hay una frase que dice “la mejor arquitectura es la sencillez”. La sencillez es escalable, si resolvemos pequeños problemas y luego los unimos, será más fácil que hacer un sistema complejo de entrada (así funciona Unix / Linux). http://es.wikipedia.org/wiki/Principio_KISS Principio 4: Estándar de Codificación PHP / Zend El lenguaje PHP y su comunidad, por años, no ha tenido ningún referente único para seguir un estándar, por consiguiente los desarrolladores usan o inventan el que más le quede cómodo. La empresa Zend Technologies, principal desarrolladora de PHP (junto al autor original) y creadora de Zend Framework, ha tomado cada vez más protagonismo (principalmente por su framework), por lo que debería ser de ahora en más nuestra referencia a seguir. Evita crear un estándar propio, usa el definido por Zend. HTTP://FRAMEWORK.ZEND.COM/WIKI/DISPLAY/ZFDEV/PHP+CODING+STANDARD+(DRAFT) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 28. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 28 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Nota del Autor: si prestas atención verás que en todos los ejemplos las llaves {} inician a la izquierda cuando es una clase o un método, no se usa el tag de cierre de php ?>, atributos y métodos privados iniciando con “_”, etcétera. Bien, todo eso lo define el estándar de Zend, así que te recomiendo que lo leas y lo sigas al pié de la letra, el estándar nos hará más fuertes ;-) “Evita crear un estándar propio, usa el definido por Zend Technologies” HTTP://FRAMEWORK.ZEND.COM/WIKI/DISPLAY/ZFDEV/PHP+CODING+STANDARD+(DRAFT) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 29. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 29 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capitulo 2 - “Introducción a los Objetos” Aquí es donde inicia todo, el primer viaje con destino aprender las profundidades de la POO ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 30. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 30 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Un sistema complejo que funciona resulta invariablemente de la evolución de un sistema simple que funcionaba. Un sistema complejo diseñado desde cero nunca funciona y no puede ser arreglado para que funcione. Tienes que comenzar de nuevo con un sistema simple que funcione." – John Gall SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 31. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 31 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Vacuidad: vaciar todos los Un niño, cuando empieza a hablar, nos conocimientos” demuestra que ya entiende el concepto de “objetos”, empieza a nombrar esas “cosas”: Como diría el legendario Bruce Lee, si tienes un vaso medio lleno no vas a poder recibir por  “vaso”, completo toda la enseñanza  ”agua”, que te quiero transmitir, por  ”papá”, consiguiente, “vaciarse” de  “mamá”, todo lo que crees que sabes  ”casa”, es lo más importante, más  “guau guau” (“perro”), que acumular conocimientos  etc. y luego simplemente rechazar lo nuevo creyendo Todos estamos sumidos en un mundo que eso “ ya lo sabes”. que tiene reglas (sepamos o no que existen, nos afectan), como cuando tiramos un Así que de aquí en adelante, olvida todo lo que objeto y este cae (gravedad), cuando pisamos crees que sabes sobre objetos y empecemos de la cola de un gato y este llora (y probablemente cero. nos arañe). “La sencillez es la mejor Nos vamos dando cuenta que generalmente no arquitectura “ manipulamos los objetos directamente ni Los “objetos” como concepto -fuera de la tenemos un completo control sobre ellos, informática- existen desde antes de la muchas veces solo interactuamos con ellos, por programación (obviamente). más que no queramos que el gato se defienda, este lo hará. Nos damos cuenta que cada uno ¿Qué es lo que intenta hacer entonces la tiene dentro una “programación” que le dice Programación Orientada a los Objetos (POO)? cómo reaccionar ante determinados estímulos Lisa y llanamente intentar simplificar la o situaciones, y descubrimos luego que un gato complejidad (“simplificar las abstracciones”) y reacciona distinto de otro gato (a pesar que tratar de representar de forma simple lo que ambos son gatos) y que no es lo mismo la vemos y manejamos todos los días… los objetos reacción de un perro con respecto a la de un que nos rodean. gato (a pesar que entre ellos existe una relación que los une como mamíferos). "Controlar la complejidad es la esencia de la programación" Por lo tanto, así son los -- Brian Kernigan objetos: pueden ser de un tipo determinado (perro, gato), también pertenecer a una misma familia (mamíferos) y a su vez ser únicos (“el gato llamado Risón”) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 32. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 32 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Lo más importante es detectar los objetos” Entonces, la Programación Orientada a Objetos no es más que eso, detectar los objetos existentes en nuestro contexto real y construirlos como si fuéramos “Dios”, dándoles un comportamiento para que estos sepan solos cómo reaccionar ante la interacción con otros objetos. A esta actividad la llamaremos “diseño” y será cuando debamos decidir cómo serán y cómo se comportarán nuestros objetos ante la interacción con otros objetos. Nada más y nada menos... y hemos logrado empezar a hablar del tema sin mostrar -hasta el momento - una sola línea de código ;-) En resumen Abre tu cabeza, borra todo lo que sabes hasta el momento de objetos y de código, y empecemos de cero, es más simple de lo que crees. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 33. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 33 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "La complejidad es destructiva. Chupa la sangre de los desarrolladores, hace que los productos sean difíciles de planificar, construir y probar, introduce problemas de seguridad y provoca la frustración de usuarios finales y administradores" -- Ray Ozzie SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 34. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 34 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 3 - “Cómo Pensar en Objetos” Veremos en este capítulo cómo detectar los objetos sin preocuparnos aún del código. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 35. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 35 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Mucho software hoy día es en cierta medida como una pirámide egipcia con millones de piedras apiladas una encima de otra, sin integridad estructural, construido por fuerza bruta y miles de esclavos." Por Alan Kay (científico de la computación) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 36. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 36 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Lo menos importante es el código” Tenemos entonces: Lo más importante –por lo menos al principio- no es jugar con el código (ya que este podrá  “Un perro”, el “objeto” propiamente funcionar, no dará error, pero conceptualmente dicho. nuestro sistema no funcionará como un sistema  “Es de color negro y blanco”, el color es “Orientado a Objetos” ni aprovecharemos todas un atributo del objeto “perro” sus virtudes), es detectar los objetos dentro de un contexto determinado.  “reacciona si le tocan la cabeza”, el comportamiento ante un estímulo “Todo problema está sujeto a un externo. determinado contexto, no existe un diseño que se adapte a todos los  “mueve la cola”, tiene acciones. posibles contextos”  “come”, otras acciones relacionadas El código con el que se construyen los objetos con su exterior/interior es meramente circunstancial, una vez que tengamos claro el diseño conceptual, luego será  “hace caca”, tiene otras acciones que seguir la receta a través del manual del lenguaje están relacionadas con su interior, y de turno. que posteriormente se exteriorizan de alguna forma. “Un niño pequeño” También es importante destacar, un poco más Empecemos por el diálogo de un niño que sutil, que existe otro objeto en este escenario y recién empieza a hablar (en este caso mi hija): se llama “Micaela”, y además existe (aunque no Micaela, de 5 años, dice: “mira el perro lo veamos) un contexto (“todo sistema tiene un negro y blanco, se llama Tito, le toco la contexto, un sistema no puede aplicarse en cabeza y mueve la cola, y si le doy de absolutamente todos los contextos”) donde comer, al rato, hace caca”. Claramente tenemos un objeto de tipo “Perro” con características bastante definidas (y probablemente con algún problema en sus esfínteres). “Más importante que codificar es detectar los objetos sin preocuparnos -aún- del código que los representará” – EP “viven” los objetos y que permite que se genere una interacción entre ambos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 37. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 37 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “El medio de comunicación” El contexto, los objetos, sus atributos, sus acciones, cuáles pueden ser De alguna forma u otra, ambos objetos tienen conocidos por otros objetos y cuales son cosas en común: existe un medio que les (o deben ser) naturalmente internos del permite comunicarse, pero a su vez ellos tienen propio objeto, para finalmente hacerlos los elementos para generar ese “diálogo”, como interactuar como en una obra de teatro así también existen “acciones” que son o en un cuento, con varios posibles “internas” e “implícitas” de cada uno: principios y finales según la historia que  Aunque Micaela –y aún el perro- no lo necesitemos contar. entienda, ambos tienen internamente distintos mecanismos de digestión y ninguno controla el mecanismo del otro.  El perro, que sabe que cuando está nervioso mueve la cola, no logra entender del todo por qué si Micaela lo acaricia, esta también se mueve. Micaela sabe que si lo acaricia su cola se moverá.  Micaela tiene una mano y el perro una cabeza, Micaela tiene acceso a su Cuando veamos los primeros ejemplos cabeza, y la cabeza es accesible para codificados entenderán un poco más de lo que que la mano pueda acariciarla. hablo ;-) Parece tonto y simple, pero así son los objetos, y en esos temas tenemos que pensar cuando diseñamos: Nota del Autor: no, no estoy bajo los efectos de alucinógenos, la POO tiene más de observación de la realidad de lo que normalmente se cree, nunca deben diseñar un sistema que “no sea coherente con la realidad”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 38. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 38 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 4 - “POO según LOS MANUALES” En la era “web” es muy probable que antes de consultar un libro impreso usemos nuestro navegador y busquemos material de lectura. Esto no está mal, el problema es que existe mucha información antigua o incorrecta, también existen demasiados “charlatanes”, por lo que deberemos ser desconfiados y selectivos con lo que leemos. Dos fuentes que son confiables y que tenemos más a mano son Wikipedia, principalmente para consultar los conceptos fundamentales que se aplican a cualquier lenguaje Orientado a Objetos, y el manual oficial de PHP, que aunque es un manual de programación y no de desarrollo (se concentra más en la sintaxis que en los conceptos), tiene mucho para enseñarnos (el resto lo haremos a través de este libro ;-)). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 39. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 39 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “La POO según Wikipedia” Amén que la introducción conceptual de Wikipedia está bien, en algunas partes puede generar confusión o no estar suficientemente explicadas. Intentaremos resaltar algunos puntos fundamentales sin reescribir el capítulo original. De todas formas, se sugiere primero la lectura del capítulo en Wikipedia http://es.wikipedia.org/wiki/POO SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 40. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 40 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Depurar código es dos veces más difícil que escribir código, por lo tanto si escribes el código tan inteligentemente como te sea posible, por definición no serás lo suficientemente inteligente como para depurarlo" SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 41. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 41 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Luego de haber leído el capítulo original en primera se pensó como funcionalidad Wikipedia, quiero resaltar los siguientes puntos por un lado y datos por otro, es decir, fundamentales: llamar a una función y pasarle constantemente datos para que los 1. La POO es un paradigma que tiene sus procese, mientras que la POO está orígenes desde antes de 1990 (a partir pensada para tener todo integrado en de este año se empieza a popularizar). el mismo objeto. Por lo tanto no es ninguna excusa (menos como Desarrollador PHP) seguir  “En la programación a la fecha desconociendo cómo trabajar estructurada sólo se escriben con POO o discutiendo si realmente es funciones que procesan datos. útil su adopción. Los programadores que emplean éste nuevo paradigma, 2. “Los objetos son entidades que en cambio, primero definen combinan estado, comportamiento e objetos para luego enviarles identidad” mensajes solicitándoles que realicen sus métodos por sí 3. Fundamental, los beneficios que mismos.” obtenemos usando este paradigma: 6. Muy importante es tener SIEMPRE en  “La programación orientada a claro los conceptos FUNDAMENTALES, objetos expresa un programa si no los tienes claros cuando como un conjunto de estos programas OO, algo está mal, seguro objetos, que colaboran entre errarás el camino que define el ellos para realizar tareas. Esto paradigma: Clase, Herencia, Objeto, permite hacer los programas y Método, Evento, Mensaje, Atributo, módulos más fáciles de escribir, Estado Interno, Componentes de un mantener y reutilizar.” objeto y Representación de un objeto. No dudes en volver a repasarlos todas 4. La razón de por qué no es necesario que las veces que lo necesites, por más todos los objetos que creemos tengan experto que te consideres, siempre un id como si fuera una clave primaria viene bien una relectura de nuestras de una tabla (con el fin de ubicar un bases. objeto en particular): 7. Características de la POO: igual que el  “De esta forma, un objeto punto anterior, es fundamental tener contiene toda la información claros estos conceptos cada vez que que permite definirlo e desarrollamos, con principal énfasis en identificarlo frente a otros el Principio de Ocultación (que es muy objetos pertenecientes a otras común confundir con clases e incluso frente a objetos Encapsulamiento), lo que explica por de una misma clase, al poder qué no deberían existir los atributos tener valores bien diferenciados públicos ni abusar de los setter/getter en sus atributos.” (tema que veremos más adelante). 5. Diferencias con respecto a la Si alguno de estos puntos no quedaron claros, Programación Estructurada versus sugiero su relectura en la Wikipedia. Programación Orientada a Objetos: la SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 42. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 42 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “POO según el manual Oficial de PHP” De la misma forma que en el punto anterior, es muy importante hacer una lectura de Referencias del Lenguaje (la base para empezar comprender PHP) y posteriormente del capítulo sobre POO en el manual oficial, aunque algunos capítulos no aborden en profundidad cada tema (lo cual es entendible si comprendemos que hablamos de un manual de sintaxis y no un tutorial para aprender a programar). Todos estos temas los veremos más adelante y haré todas las referencias oportunas al manual oficial, pero aquí la lista de temas básicos que trata. Clases y Objetos (PHP 5) Table of Contents 1. Introducción 2. Las Bases 3. Auto carga de Objetos 4. Constructores y Destructores 5. Visibilidad 6. Alcance del operador de resolución (::) 7. La palabra reservada 'Static' 8. Constantes De la Clase 9. Abstracción de Clases 10. Interfaces de Objetos 11. Sobrecarga 12. Interacción de Objetos 13. Patrones 14. Métodos mágicos 15. La palabra reservada 'Final' 16. Clonado de Objetos 17. Comparación de Objetos 18. Reflección 19. Type Hinting SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 43. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 43 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Medir el progreso de programación en líneas de código es como medir el progreso de construcción de un avión en peso" Bill Gates SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 44. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 44 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 5 - “Empezar a plasmar los objetos en un diseNo” En este capítulo empezaremos a ver cómo transformar los objetos que detectamos en nuestra observación de la “realidad” en algo “informáticamente” palpable. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 45. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 45 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Hay dos maneras de diseñar software: una es hacerlo tan simple que sea obvia su falta de deficiencias, y la otra es hacerlo tan complejo que no haya deficiencias obvias" -- C.A.R. Hoare SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 46. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 46 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Cómo representar la estructura de los objetos” 1) “Los Objetos tienen Atributos, En un capítulo anterior habíamos hablado de Comportamientos y Estados” una situación de la realidad donde una niña (mi hija) interactuaba con un perro, así que vamos Todos los objetos tienen a ir por partes y tratar de representar lo que “atributos”,”comportamientos” podemos interpretar del texto que está en un (“métodos”) y un “estado”. Este lenguaje natural y nos describe claramente los último no es más que la objetos y sus relaciones: información que tienen los atributos en un momento dado. Micaela, de 5 años, dice: “mira el perro negro y blanco, se llama Tito, le toco la 2) Un perro se llamará “Tito” y otro “Ruffo”, cabeza y mueve la cola, y si le doy de pero el atributo es el mismo (“nombre”). Si comer, al rato, hace caca”. mañana el perro cambia de nombre, lo que cambia es “su estado” y el mecanismo para Si nos concentramos en el perro, tenemos que: cambiar el estado serán sus métodos (“cambiar el nombre”). Atributos  Color  Nombre Comportamiento  Se le puede tocar la cabeza  Mueve la cola  Puede comer  Sabe hacer sus necesidades Y se desprende prestando atención a la lectura del texto que define nuestro contexto. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 47. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 47 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 3) “La clase, un molde para construir objetos” Este ejemplo es muy usado para tratar de transmitir el concepto que hay detrás. Podríamos decir que si “jugáramos a ser Dios”, primero definiríamos un diseño de cómo va a ser la criatura que queremos crear, haríamos un “molde” a partir de ese diseño, y posteriormente podríamos crear “vida” con similares características, pero que siempre serán “objetos únicos”. “Crear Personas” Por ejemplo, si quiero crear “Personas” diría que todas tendrán un sexo (masculino / femenino), dos piernas, dos brazos, una cabeza y pelo sobre ella (es un diseño simple para un contexto simple, si fuera otro el contexto, muy probablemente debería cambiar mi diseño). “Crear Perros” Por ejemplo, podría decir que los “Perros” también tendrían un sexo, pero ahora tendrían cuatro patas, una cabeza y pelo sobre todo su cuerpo. Para ambos ejemplos ya cuento con dos moldes, el de Personas y el de Perros, por lo tanto ahora puedo crear a Micaela y a Tito, pero también podría crear a Martina y a Ruffo, por lo que tendríamos dos personas y dos perros, con características similares, pero que serían a su vez criaturas únicas, identificables y distinguibles entre las demás criaturas, aún entre las criaturas del mismo tipo (aunque se llamaran igual y tuvieran los mismos rasgos, serían solo parecidos). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 48. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 48 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 4) “Los atributos y comportamientos pueden Cómo se debería leer este diagrama: ser públicos o privados”  Todo lo que se encuentre dentro de la Existirá información y comportamientos que representación “Perro” es “interno y serán conocidos por otros objetos (“acceso privado” (invisible para el exterior) y lo público”) y esto permitirá que se pueda generar que se encuentre “una parte dentro y una interacción entre ellos. También existirá otra afuera” será nuestra “interfaz” información y comportamientos que serán con el exterior, los “comportamientos internos de cada objeto (“acceso privado”) y no públicos” del objeto que serán serán conocidos por los demás objetos. invocados por los “mensajes” enviados por otro objeto que quiere interactuar Un diseño posible para nuestro Perro podría con nosotros. ser:  Un objeto de tipo “Perro” tiene como atributos su “color” y su “nombre”  Dentro de los posibles Perro comportamientos públicos de nuestro Atributos perro podrían ser “comer”, “recibir una color caricia”, etc. nombre  Dentro de los posibles comportamientos privados de nuestro Comportamiento perro podría ser “hacer la digestión”, comer que muy probablemente será activada a través de otros métodos (como Hacer digestión Recibir caricia “comer”). Mover la cola Hacer sus necesidades SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 49. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 49 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Qué es lo que vería Micaela desde el exterior: Lo que sí sucederá es que Micaela generará Perro indirectamente que se active el mecanismo interno de digestión al darle de comer al Perro (“Micaela le dice al perro que coma”, lo que se debe traducir como “Micaela le envió un mensaje al perro”), pero esto ocurrirá sin que Micaela sepa que sucede, solo podrá apreciar Comportamiento sus resultados cuando el perro haga sus comer necesidades (ya que las necesidades no salen solas). Recibir caricia Ahora bien, ¿de quién es la responsabilidad de Mover la cola definir todas estas reglas? Si, obviamente, la responsabilidad es nuestra, y Hacer sus necesidades un diseño será más débil o más robusto de acuerdo a cómo nosotros pensemos que deben reaccionar nuestros objetos a los mensajes que recibirán del exterior y cuanto oculten de sus propios detalles de implementación. Solo podríamos interactuar con lo que es “público” del diseño, como así lo decidimos. Ahora la pregunta sería “¿Qué debería ser público y qué debería ser privado?”, bueno, intentemos usar el sentido común:  el perro necesita poder interactuar con su exterior de alguna forma, pero existirán “detalles” que no conciernen al exterior ni nos interesa que otro objeto pueda modificar a su antojo. Por ejemplo, Micaela no tiene por qué saber cómo es el mecanismo de digestión de un perro, qué órganos entran en juego durante todo el proceso, es más, por la vida del perro creo que tampoco Micaela debería poder tener la potestad para cambiarlo a su antojo (ya que seguro estaría en peligro la vida del perro). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 50. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 50 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Nota del Autor: esto es un ejemplo teórico para tratar de transmitir varios conceptos, como todo diseño, tendrá debilidades y fortalezas, y si cambiamos de contexto, muy probablemente este diseño no servirá (no dudo que en este momento estarán pensando “que pasaría si…” y muy probablemente se encuentren con que algo no se puede hacer... bueno, vayamos paso a paso y veremos de a poco el horizonte, pero ya les voy adelantando: no existen diseños que pueda funcionar en absolutamente todos los contextos posibles, por esta razón es importante definir “el contexto” de nuestro sistema. Nota: a menos que estemos hablando concretamente de patrones de diseño, pero aún así se define en qué contextos se podrían aplicar y en cuales no. Por ejemplo: el diseño de una clase Persona no será exactamente el mismo si estamos hablando de un sistema de reserva de películas, una universidad con alumnos o un sistema de salud. Tendrán cosas comunes, pero su diseño no será necesariamente el mismo. En mi opinión no existe el “100% de reuso puro”, existirán componentes que dada su naturaleza sí podrán usarse en distintos contextos y otros directamente no, a menos tal vez que hayamos pensado de entrada que así debíamos diseñar nuestros componetes: “reusables en varios contextos”, aunque esto podría aumentar exponencialmente la complejidad del componente o de los sistemas. Para más información sobre el apasionante tema sobre “diseño” se recomienda leer el siguiente artículo de Martín Fowler: “¿Ha muerto el diseño?” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 51. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 51 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Las clases se construyen en la etapa de diseño donde definimos qué es lo que queremos crear. Lo que creamos a partir de ellas es un objeto que “tendrá vida” (será lo que verdaderamente se ejecutará en nuestro sistema) y a la vez “único” (podrán existir muchos objetos del mismo tipo, pero podremos interactuar con ellos e identificarlos de forma única). Dentro de las definiciones de la clase tenemos los atributos y los comportamientos que tendrá nuestra creación, algunos de ellos serán públicos y otros serán privados. Todo lo que definamos como público será nuestra “conexión” con el exterior y permitirá la interacción entre los objetos. Esta interacción se dará a través de envíos de mensajes entre objetos, como por ejemplo “Micaela le da de comer al perro”, por lo que existirán dos objetos, uno que puede “comer” y otro que puede decirle al otro “que coma” (si no existen estos métodos, el perro directamente no hará nada y estará desconectado con el exterior). Esto se clarificará cuando empecemos a usar los diagramas UML (similares al diagrama presentado anteriormente) y a traducirlos en código concreto y ejecutable. Tienes dudas? Quieres hacer una consulta? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 52. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 52 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Codifica siempre como si la persona que finalmente mantendrá tu código fuera un psicópata violento que sabe dónde vives" -- Martin Golding SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 53. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 53 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 6 - “Introducción a UML” De la misma forma que a veces nos apoyamos en un dibujo para tratar de comprender y razonar un problema, muchas veces complejo, considero que es fundamental contar con una “herramienta gráfica” (para armar “diagramas”) que nos permita discutir y elaborar diseños sin tener que distraernos en los superfluos y cirscunstanciales detalles de la codificación según el lenguaje que necesitemos usar. Diseñar Orientado a Objetos es independiente del lenguaje de programación, por lo tanto usaremos UML, un lenguaje “gráfico” independiente de la implementación. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 54. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 54 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “En las batallas te das cuenta que los planes son inservibles, pero hacer planes es indispensable” - Dwight E. Eisenhower SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 55. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 55 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Aquí es donde entra el Lenguaje Unificado de “UML y el público objetivo” Modelado (UML), y a pesar que existe mucho A pesar que existen reglas software para documentar usando diagramas, para hacer cualquier pero bien podemos decantarnos por una opción diagrama UML, los diseños “libre” como ArgoUML (multiplataforma), siempre deben estar StarUML (win) o Umbrello (lin) sujetos a interpretación y su nivel de detalle dependerá de nuestro “UML, el medio y no el fin en “público objetivo”. sí mismo” Si vamos a usar un diagrama para presentarles a Como bien dice la frase, los diagramas UML son programadores inexperientes cómo deberían el medio y no el fin, sirven para simplificar desarrollar un sistema, este diagrama debería notablemente las discusiones sobre disponer de la mayor cantidad de información y “abstracciones” y mejoran la comunicación no dar por sobreentendido nada. entre personas, ya sean desarrolladores como otros roles dentro de un mismo proyecto. Otra Por el contrario, si nuestro público son de las ventajas es que atrasa la “codificación desarrolladores “seniors” con experiencia en temprana” y facilita estar más tiempo en la UML, bastará con detallar solo la información etapa de diseño. pertinente al problema que se quiere resolver y el resto de información se obviará para evitar Existen distintos tipos de diagramas, cada uno “ruido extra”. más adecuado que el otro según la situación (si tratáramos con el cliente directamente los Un equipo con experiencia en UML debería diagramas de Casos de Uso serían lo más poder recibir cualquier diagrama e indicado). implementarlo de forma mecánica sin tener siquiera que razonar el diseño, lo cual significa Para lo que a nosotros nos concierne, vamos a que el diagrama siempre se traduce de la misma apoyarnos en ellos para simplificar nuestro forma, un elemento del diagrama siempre razonamiento y poder detectar más fácilmente tendrá la misma traducción en código, no cuando un diseño no es correcto y discutir importa el lenguaje que usemos. cómo mejorarlo y para ellos nos concentraremos en los diagramas de clases y diagramas de paquetes. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 56. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 56 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “UML es independiente del Consejo #1 lenguaje” “No aprendas POO ni te apoyes en libros sobre Como bien lo dice la frase, UML es POO que no usen UML” independiente del lenguaje. Sirve para representar muchas cosas, pero en lo que Consejo #2 respecta a la POO, cada dato que se impregne “No empieces a desarrollar con POO si no tienes en el diagrama podrá ser traducido a cualquier antes –como mínimo- un pequeño diagrama de lenguaje que permita implementar el clases explicando la relación entre ellas” paradigma de los Objetos. Si el lenguaje de turno no lo soportara en un 100%, habrá que Consejo #3 interpretar el diseño UML y hacer los ajustes pertinentes en el código. “Lávate los dientes antes de dormir, cuando te levantes, y luego de cada comida” Algunas veces el diagrama no puede representarse exactamente en un lenguaje, por lo que deberemos ser creativos y quedarnos con el concepto que nos busca transmitir el diseño (este caso lo veremos concretamente con PHP y su problema histórico de representar explicitamente los “paquetes”). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 57. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 57 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En resumen Los diagramas UML permiten unificar y simplificar la comunicación en un proyecto, como así también apoyar el razonamiento en la etapa de diseño de una solución. Existen gran variedad de diagramas y son tan importantes como los diagramas MER/DER que se usan para diseñar una base de datos. Nadie que desarrolle un sistema se le ocurriría crear una base de datos directamente en el servidor sin definir anticipadamente una estrategia en un documento. De la misma forma deberíamos pensar a la hora de hacer sistemas Orientado a Objetos. Quieres solicitar más información sobre algún punto? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 58. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 58 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 7 - “Cómo representar una clase en UML” Empezamos con los primeros pasos en el Lenguaje Unificado de Modelado (UML) y usa las herramientas que te sean más cómodas, puede ser ArgoUML , Gliffy, Dia, etc (existen muchos programas más), o directamente dibujando en un papel o una pizarra (lo que puedes luego fotografiar y subir a una wiki). Lo que importa son los conceptos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 59. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 59 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Primero resuelve el problema. Entonces, escribe el código" -- John Johnson SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 60. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 60 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com PHP tiene Estándares: aunque no lo crean, Mi primer diagrama UML Zend, la empresa que desarrolla el lenguaje y el Definamos un contexto para luego diseñarlo framework, tiene definido un documento que con UML: especifica los estándares de codificación –que para no ser menos- seguiremos al pié de la “Una persona tiene nombre, apellido y fecha de letra. nacimiento, cuando se le pregunta qué edad tiene, responde con su edad que calcula en base a la fecha de nacimiento” “Conceptos Generales” Primer Regla: de nomenclatura, los nombres de las clases son siempre en singular y la primer Y el diagrama UML debería verse de la siguiente letra de cada palabra en mayúsculas manera: (CamelCase), al revés de los nombres de las tablas de una base de datos, generalmente en plural y en minúsculas:  Tablas en base de datos: personas, animales,usuarios, usuarios_administradores  Clases en POO: Persona, Animal, Usuario, UsuarioAdministrador SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 61. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 61 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Este diagrama se debe leer de la siguiente soporta exactamente, recuerda que forma: UML es independiente del lenguaje)  La Sección #3 es para definir los métodos de nuestra clase (CamelCase, igual que con los atributos), la visibilidad de cada uno, los parámetros que pueden recibir y si retornan o no alguna información (para ambos casos, especificando el tipo de dato). Regla: “todos los atributos de una clase son por defecto no-públicos”.  La Sección #1 es para definir el nombre Existe una convención (que casi no se de la clase (como explicamos al discute) desde los principios de la POO que principio, usando CamelCase). si cualquiera desde el exterior puede conocer y modificar los atributos de un  La Sección #2 es para definir los objeto, y por ende, su “estado”, todo diseño atributos de nuestra clase (CamelCase, será débil (este tema lo veremos más en pero a diferencia de las clases, inician profundidad cuando tratemos el tema con minúscula), la visibilidad de cada “métodos accesores / modificadores”). uno (el signo “-“ para privado, el signo “+” para público) y qué tipo de dato debería ser (no importa si el lenguaje lo SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 62. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 62 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo se traduce en código Sección #2 – los atributos de la clase Vayamos por partes (dijo Jack, “El Según el diagrama, tenemos 3 atributos, todos Destripador”), empieza por arriba y sigue “privados” (signo “-“) y dos serán de tipo secuencialmente hacia abajo, y la traducción se “String” (cadena de caracteres) y uno de tipo hará muy simple y natural. Date (fecha). Sección #1 – nombre de la clase Siguiendo la nomenclatura del estándar, deberíamos primero crear un archivo / fichero con el mismo nombre que la clase: Persona.php Posteriormente, todo se traduce en: <?php class Persona { } Aquí es donde tenemos que interpretar el diagrama y ajustarlo a nuestro lenguaje. Si quisiéramos traducir esta clase a Java no tendríamos problema porque existen “clases base” (ya que en Java “todo es un objeto”) como String, Integer, Date, etc. Pero, como no tenemos esta posibilidad en PHP (aún, espero que en un futuro cercano sí), podemos enfrentarlo de dos maneras, la manera simple y pragmática, o la estricta y dogmática. Estándar de Codificación Como podrán apreciar en el primer código de ejemplo sucede algo atípico: nuestra clase tiene las llaves a la izquierda y no existe el tag de cierre ?> Todo corresponde al estándar de codificación de Zend, particularmente para el último caso se omite cuando el archivo usará solo código PHP y no con HTML embebido. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 63. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 63 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Versión pragmática Lo máximo que podríamos hacer es: <?php <?php class Persona class Persona { { private $_nombre; private $_nombre = ''; private $_apellido; private $_apellido = ''; private $_fechaNacimiento; private $_fechaNacimiento = ''; } } Comentario aparte: perfectamente podríamos haber usado una traducción directa de los Al asignarle un valor por defecto de tipo String, atributos y decir que son $nombre, $apellido y su atributo sería de tipo String y cumpliríamos $fechaNacimiento, pero como estamos exactamente con el diagrama, a no ser por la siguiendo el estándar definido por Zend, fecha, porque no tenemos nada parecido a usaremos el agregado $_ para todos los Date. atributos que son “privados”. No olvidar, esto Si tuviéramos la necesidad de definir un Integer, no es un problema que debe contemplar UML, ya es un problema del lenguaje de turno, en simplemente asignaríamos un 0 a nuestro atributo, por ejemplo: nuestro caso, PHP. Versión dogmática private $_edad = 0; Por ejemplo, como Java es un lenguaje de SUGERENCIA, sean PRAGMÁTICOS: no conviene perder mucho más tiempo con esto ya “fuertemente tipado”, cada uno de los atributos que como PHP es de asignación dinámica de se traducirían de la siguiente forma: tipos, el hecho que definamos en el comienzo Código JAVA: un valor por defecto no asegura que se vaya a mantener, y UML es un medio y no un fin en sí public class Persona{ private String nombre; mismo. El mensaje que nos debe quedar es que private String apellido; ese atributo debe manejar este tipo de dato, y private Date fechaNacimiento; } nosotros como desarrolladores estamos siendo notificados de ello y somos responsables de ver Pero como PHP es un lenguaje de “tipado luego qué controles deberemos agregar para dinámico” no requiere definir inicialmente un que se cumpla en el resto de la clase. tipo para sus variables, el tipo es definido dinámicamente cuando se hace una asignación Por ejemplo, imaginemos lo siguiente: “la de valor (y su uso también dependerá del documentación que nos entregó nuestro contexto en donde se encuentre) director de sistemas dice que manejarán valores de tipo Date en el atributo fechaNacimiento” por consiguiente no deberíamos permitir el uso de algo que no sea de tipo Date, así tendrá coherencia el diseño con la implementación. Si el código no respeta el diseño, el código está mal y hay que corregirlo. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 64. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 64 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Sección #3 – los métodos de la clase información escrita explicando los posibles detalles o problemas de la implementación, o Finalmente, la traducción de los métodos. Aquí simplemente se hará una reunión para tratar el tenemos un método público (signo “+”), que no tema y sacar dudas. recibe parámetros (los paréntesis están vacíos) y luego de los “:” representan qué tipo de valor retornará (en este caso será un número entero “El Constructor” que representará la edad). Si tuviéramos la necesidad de documentar El resultado en código sería: alguna particularidad del constructor, lo que <?php generalmente se hace class Persona { es agregar un método private $_nombre; con el mismo nombre private $_apellido; de la clase, lo que private $_fechaNacimiento; representaría “el public function decirEdad() constructor” de la clase { /* calculo la fecha a partir de (sintácticamente sería similar a como lo hace $_fechaNacimiento */ Java y cómo lo hacía PHP4, ya que cambia en PHP5 por la palabra reservada __construct() ). return $edadCalculada; } Nota: al no existir el tipo Date lo que se } hace es recibir un parámetro y pasarle el valor al atributo que se encuentra protegido internamente en la clase En este ejemplo se puede ver un detalle (“atributo privado”). importante: ¿cómo y cuando se define el El elemento “void”: significa “vacío”, “nada”, valor de la fecha de es decir, debemos leerlo como “este método nacimiento de la no retorna nada”. En los diagramas UML persona? podemos encontrar que todo lo que no devuelva nada o no tenga tipo, es de tipo Respuesta: en ningún “void”. También podemos encontrar que momento, el diagrama directamente se omita y no se muestre nada UML no dice nada, aquí está supeditado al al final del método (eliminado “:void” del final). público objetivo de la documentación y a su interpretación. Cabe aclarar que cuando se entrega un diagrama UML no solo van los dibujos, también se acompañan con más SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 65. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 65 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Persona.php <?php class Persona { private $_fechaNacimiento; /** * * @param string $fechaNacimiento 5/8/1973 */ public function __construct($fechaNacimiento) { $this->_fechaNacimiento = $fechaNacimiento; } public function decirEdad() { return $this->_calcularEdad(); } private function _calcularEdad() { $diaActual = date(j); $mesActual= date(n); $añoActual = date(Y); list($dia, $mes, $año) = explode("/", $this->_fechaNacimiento); // si el mes es el mismo pero el dia inferior aun // no ha cumplido años, le quitaremos un año al actual if (($mes == $mesActual) && ($dia > $diaActual)) { $añoActual = $añoActual - 1; } // si el mes es superior al actual tampoco habra // cumplido años, por eso le quitamos un año al actual if ($mes > $mesActual) { $añoActual = $añoActual - 1; } // ya no habria mas condiciones, ahora simplemente // restamos los años y mostramos el resultado como su edad $edad = $añoActual - $año; return $edad; } } ¿Cómo se prueba? $persona = new Persona('5/8/1973'); echo $persona->decirEdad(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 66. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 66 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Probando el objeto en un Probando que los objetos son contexto determinado únicos Nuestra clase ya está lista y definida, ahora Creamos dos instancias a partir de la clase habría que probar de crear a partir del “molde” Persona y luego imprimimos en pantalla la un “objeto” y probarlo. estructura interna de cada uno de los objetos CRITERIO: como todo debería ser un creados con un var_dump. objeto, todos los archivos deberían Como salida obtendremos la radiografía interna tener la misma nomenclatura. Pero en de cada objeto: nuestro caso particular de la web, siempre tenemos una página inicial object(Persona)#1 (3) { “index”, por lo que fijaremos de ahora ["_nombre:private"]=> NULL en más el siguiente criterio: en los ["_apellido:private"]=> NULL diagramas representaremos la clase ["_fechaNacimiento:private"]=> string(8) "5/8/1973" } “Index” pero a la hora de object(Persona)#2 (3) { implementarla crearemos el archivo en ["_nombre:private"]=> NULL minúsculas “index.php” (o de lo ["_apellido:private"]=> NULL contrario nuestro servidor web no lo ["_fechaNacimiento:private"]=> string(8) "5/8/1973" } encontrará) y en su interior podemos crear o no una clase de Index (quedará librado para discutir más adelante). Si prestamos atención, el primero dice: Para simplificar y no perder el foco en lo object(Persona) #1 y object(Persona) #2 importante, probar la clase Persona, haremos el mínimo código necesario para index.php. Ambos números (#1 y #2) son los identificadores internos del sistema. Por cada Listo, creamos nuestro contexto en index.php, objeto que creamos en el contexto de donde creamos el objeto unaPersona a partir de index.php (mientras esté ejecutando) se irá la clase Persona, definimos su fecha de incrementando secuencialmente y por más que nacimiento, y posteriormente le pedimos que los datos de los atributos sean idénticos nos diga su edad. (“estado”) estamos hablando que existen en realidad “objetos distintos y únicos”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 67. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 67 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Vimos cómo se representa una clase en UML, que no necesariamente la traducción es literal ya que dependemos del lenguaje, pero que UML siempre es independiente, no habla de sintaxis particular y siempre está sujeto a una interpretación. ¿Algo no quedó claro? No te quedes con dudas Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 68. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 68 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 8 - Ejercicio "Micaela y el Perro" Lo más importante es tener bien claros los conceptos, pero fundamental es saber aplicarlos. Iremos planteando varios ejercicios que tú mismo puedes hacer y revisar su solución más adelante. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 69. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 69 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Programar sin una arquitectura o diseño en mente es como explorar una gruta sólo con una linterna: no sabes dónde estás, dónde has estado ni hacia dónde vas" -- Danny Thorpe SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 70. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 70 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos A partir de todos lo expuesto anteriormente se solicita: 1. Hacer los diagramas UML de las clases (y codificar cada una de ellas) del ejemplo "Micaela y el Perro" (se sugiere revisar todo el material, ya que hay referencias en varios capítulos). 2. Crear todas las clases en archivos independientes: Persona.php y Perro.php 3. Crear un index.php que use las clases que se crearon. Atención: 1. Solo con lo visto hasta el momento, nada de diseños complejos, solo clases involucradas, atributos y métodos. 2. Evitar toda codificación extra e innecesaria (KISS). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 71. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 71 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución  Mi sugerencia es no hacer uso de los _set y _get que incorpora PHP5, ya que La idea de cada tarea es aplicar y extender los en la mayoría de los casos –según mi conocimientos que se debieron haber adquirido experiencia- debilitan los diseños al con la lectura de los capítulos anteriores. generar efectos de “atributos públicos”. Estos mismos ejercicios fueron realizados por No siempre lo genérico es bueno, como alumnos de los talleres a distancia y estos son en este caso. los errores más habituales que se pueden cometer:  Si el método retorna algo de tipo “Comer”, por ejemplo  A partir de las clases UML se deben darComida():Comer, eso significa que generar siempre archivos aparte, por el retorno es una clase Comer, por lo clase, con la nomenclatura Persona.php cual no es correcto si el retorno en sí es y no persona.class.php o persona.php un String, por lo tanto lo correcto es: (debemos usar el Estándar de darComida():String. Codificación de Zend)  Los atributos deben iniciar siempre en  Las llaves “{}” van abajo solo en las minúsculas, igual que los métodos clases y métodos, para ningún caso más, ni if, ni while, etc (estándar Zend)  No es necesario especificar el constructor del diagrama si este no  Los atributos y métodos privados aporta nada relevante. deben llevar delante “_” (estándar Zend), por ejemplo: $_nombre, _hacerDigestion()  Siempre realizar “exactamente” lo que se solicita (a menos que solicite explícitamente lo contrario), no más, debemos ajustarnos siempre a los requerimientos que nos solicitan (Principio KISS). Debemos evitar la “sobre-ingeniería” y extender la funcionalidad de una clase, aumentando innecesariamente su complejidad. En un proyecto, donde hay más de un desarrollador es importante que la arquitectura se mantenga “simple”, de lo contrario, cuando crezca, será más costoso mantener el sistema. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 72. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 72 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Aplicación del “Principio  Siempre cuando diseñen una clase, KISS” “pararse literalmente sobre ella” razonando qué es lo que debería ver o Si en una empresa/proyecto para hacer un conocer esta, sin entrar a pensar qué es sistema cada desarrollador (con toda la mejor lo que deberían hacer las demás clases. voluntad del mundo) agrega un “extra” y trata Tan importante como diseñar qué de hacer la “super clase” (agregar funcionalidad hacen es entender qué no deberían no solicitada), la complejidad aumentará hacer. exponencialmente. Es recomendable ajustarse a los  Seguir el principio de diseño OO: “Una requerimientos, a menos que estos digan que clase, una única responsabilidad”, si deben cubrir todos los posibles errores, tiene más de una responsabilidad, debe situaciones, etc, pero de todas formas habrá estar haciendo más de lo que le corresponde, y deberá descomponerse que definir un criterio o un límite. en otra clase. Recuerda: un diseño está atado siempre a un contexto, si cambia el contexto, muy  Finalmente, con él o los objetos de más probablemente deberá cambiar el diseño. No alto nivel, empezar a interactuar con existen diseños que sirvan para absolutamente los objetos de más bajo nivel, sin todos los contextos posibles, por lo tanto, es interesar cómo están construidos por recomendable hacer un diseño concreto para dentro y qué hace su código interno; un contexto concreto. solo hay que tomar los objetos y pedirles la información o el Sugerencias para enfrentar comportamiento que necesitamos de los diseños ellos (“interfaz pública”). En general, tratar de:  Y el más importante de todos, Mantener un “Diseño Simple” en todos  Empezar a pensar el diseño a partir de los sentidos, evitar complejidad los objetos de más bajo nivel (los más innecesaria. Por ejemplo, puedes tomar simples) y en ese momento “olvidarse la siguiente métrica: si un método no se del bosque” (así no se pierde el foco de puede visualizar en una sola pantalla, lo que se está tratando de abstraer, el hay algo que evidentemente está mal y objeto concreto como entidad hay que descomponerlo en varios independiente). métodos (refactoring), etc. Sugerencia: Prefiere “Simple” sobre “Complejo” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 73. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 73 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Propuesta de Diseño 1 Para este caso planteo otro posible diseño siguiendo al pié de la letra lo comentado en los capítulos anteriores. Diagrama UML Diagramas usando Netbeans 6.5 + plugin UML SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 74. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 74 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Traducción de UML a PHP Perro.php <?php class Perro { private $_color; private $_nombre; private $_estomagoLleno = false; public function __construct($nombre, $color) { $this->_nombre = $nombre; $this->_color = $color; } public function recibirCariciaCabeza() { return $this->moverLaCola(); } public function moverLaCola() { return 'estoy moviendo la cola!'; } public function comer() { $this->_estomagoLleno = true; sleep(5); return $this->_hacerDigestion(); } public function hacerNecesidades() { return 'hago caca!'; } private function _hacerDigestion() { $retorno = null; if($this->_estomagoLleno){ $this->_estomagoLleno = false; $retorno = $this->hacerNecesidades(); } return $retorno; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 75. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 75 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Persona.php <?php class Persona { private $_edad; private $_nombre; public function __construct($nombre, $edad) { $this->_nombre = $nombre; $this->_edad = $edad; } public function darCariciaPerro($perro) { echo $perro->recibirCariciaCabeza() . '<br>'; } public function darDeComerPerro($perro) { echo $perro->comer() . '<br>'; } } index.php <?php require_once 'Persona.php'; require_once 'Perro.php'; $persona = new Persona('Micaela', 5); $perro = new Perro('Tito', 'blanco y negro'); $persona->darCariciaPerro($perro); $persona->darDeComerPerro($perro); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 76. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 76 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Propuesta de Diseño 2 Atención con la “sobre-ingeniería”, hay que evaluar si estas mejoras no son demasiadas porque el contexto no lo requiere. Cambios  Se hace más genérico, no es dependiente de un perro, puede acariciar otras cosas que sean “acariciables” (otros animales).  Se crea una clase Index para mostrar cómo sería hacerlo 100% POO, usando la invocación sin instancia, directamente ejecutando la clase (más adelante profundizaremos).  Las clases nunca imprimen información, siempre retornan. Solo la primer clase que invoca toda la acción del sistema (“Clase Controladora”) hace la impresión que genera la página html (ubicada en el archivo index.php) Diagrama UML SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 77. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 77 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Traducción UML a PHP Perro.php <?php class Perro { private $_color; private $_nombre; private $_estomago; public function __construct($nombre, $color) { $this->_nombre = $nombre; $this->_color = $color; } public function tocan($lugar) { $retorno = null; if($lugar == 'cabeza'){ $retorno = $this->_moverCola(); } return $retorno; } private function _moverCola() { return 'estoy moviendo la cola!'; } public function comer($comida) { $this->_estomago = $comida; sleep(5); return $this->_hacerDigestion(); } private function _hacerDigestion() { $retorno = null; if(isset($this->_estomago)){ $this->_estomago = null; $retorno = $this->_hacerNecesidades(); } return $retorno; } private function _hacerNecesidades() { return 'hago caca!'; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 78. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 78 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Persona.php <?php class Persona { private $_edad; private $_nombre; public function __construct($nombre, $edad) { $this->_nombre = $nombre; $this->_edad = $edad; } public function tocar($objeto, $lugar) { return $objeto->tocan($lugar); } public function darComer($objeto, $comida) { return $objeto->comer($comida); } } index.php <?php require_once 'Persona.php'; require_once 'Perro.php'; class Index { public function ejecutar() { $persona = new Persona('Micaela', 5); $perro = new Perro('Tito', 'blanco y negro'); echo $persona->tocar($perro, 'cabeza') . '<br>'; echo $persona->darComer($perro, 'carne') . '<br>'; } } $index = new Index(); $index->ejecutar(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 79. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 79 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Siempre se pueden plantear más de un diseño y esto quedará a discusión del equipo de trabajo y ajustándose a un contexto determinado. Se plantearon un par de diseños que no necesariamente son “la única solución posible” y se busca extender la comprensión de los conceptos tratados. Encontraste algún error? Quieres enviar una sugerencia? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 80. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 80 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 9 - Los métodos "getter / setter" o "accesores / modificadores" He visto mucha documentación que habla sobre el tema de los métodos "getter / setter", o traducido al castellano los métodos "accesores / modificadores", y la mayoría se va a los extremos, perdiendo de explicar de forma simple la razón de su existencia, y algo más importante, por qué no deberíamos abusar de esta práctica. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 81. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 81 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Si la depuración es el proceso de eliminar errores, entonces la programación debe ser el proceso de introducirlos" -- Edsger W. Dijkstra SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 82. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 82 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com El origen de la necesidad de Nosotros, como "desarrolladores los "set y get" para los experimentados", nos sentimos molestos atributos por la tontería que acaba de hacer el "estudiante"... ahora la pregunta es, como En PHP4 todos los atributos de un objeto son evitamos que esto suceda? siempre atributos públicos, es decir, cuando creamos una instancia del objeto a partir $unUsuario->nombre = strtoupper($unUsuario->nombre); de la definición de la clase, tanto para leerlos como para modificarlos. if (is_null($unUsuario->clave)){ $unUsuario->clave="clavePorDefecto"; Definición de la clase "Usuario" en PHP4 } class Usuario{ var $nombre; Uno de los problemas aquí es que PHP4 no var $nombreReal; soporta la definición del "alcance" (o var $edad; var $clave; también llamada "visibilidad") de los } atributos y métodos, algo habitual en cualquier lenguaje serio de tipo "Orientado Creo el objeto "unUsuario": a Objetos". Esto hace que -aunque no nos guste- el desarrollador de turno pueda $unUsuario = new Usuario(); hacer lo que quiera con los atributos de cualquier objeto a su alcance. En este momento el usuario está vacío, pues sus atributos no tienen ningún valor asignado. Por lo tanto, le daremos sentido a Migremos la sintaxis a PHP5 este objeto: PHP5, consciente de este problema, implementa la definición de "visibilidad" de $unUsuario->nombre = "eplace"; los atributos y métodos, como lo haría Java $unUsuario->nombreReal = "Enrique Place"; o .Net. Si hiciéramos una migración $unUsuario->edad = "33"; $unUsuario->clave = "pepe"; "mecánica" de nuestro código, este cambiaría la sintaxis a esta forma (ya que la sintaxis "var" pasa a desuso y esta definía a Definamos un contexto de los atributos siempre "públicos"): ejemplo class Usuario { Supongamos ahora que nuestro sistema es public $nombre; mantenido por varios desarrolladores y que public $nombreReal; una parte del sistema es mantenida por un public $edad; "estudiante de programación" que decidió public $clave; } unilateralmente que cuando le llegue el objeto "unUsuario" le pondrá siempre el Ahora disponemos de las siguientes nombre en mayúsculas y le colocará una opciones gracias a la nueva sintaxis: public, clave por defecto si esta está vacía. private y protected. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 83. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 83 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Ahora bien, si queremos que el "estudiante" no Por un tema de principios de la POO los pueda modificar nuestros datos, podemos pasar atributos de los objetos deben ser siempre a colocar todos los atributos como "private": "privados" (concepto "encapsulación": no son accesibles desde fuera del objeto, solo el objeto class Usuario tiene la potestad de usarlos directamente) y se { deberán crear métodos públicos que sustituya private $_nombre; private $_nombreReal; una u otra operación, o ambas, cada vez que la private $_edad; situación lo amerite: private $_clave; }  un método "setter" para "cargar un valor" (asignar un valor a una variable) Listo, ahora cuando el "estudiante" quiera ver o modificar un atributo, el sistema le enviará un  un método "getter" para "retornar el error. El problema ahora es que nosotros valor" (solo devolver la información del queremos que: atributo para quién la solicite). 1. La edad se pueda saber y cambiar en Veamos cómo se resuelve, paso a paso. todo momento. 2. Se pueda saber el nombre del usuario, pero no modificarlo 3. No nos interesa que se sepa el nombre real del mismo 4. Pero queremos que pueda colocar una nueva clave si el usuario se la olvida, pero no saber la que existe actualmente Esto no lo podemos hacer ni teniendo todos los atributos públicos como sucedía con PHP4 ni restringiendo toda la visibilidad como nos permite ahora PHP5. ¿Cómo se hace entonces? SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 84. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 84 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimiento 1 Requerimiento 2 Poder saber el nombre del usuario pero no La edad se puede acceder y modificar en todo modificarlo, para eso hay que agregar solo un momento, por consiguiente se deben agregar método get para ese atributo: los dos métodos, un "get" y un "set" para ese atributo: class Usuario class Usuario { { private $_nombre; private $_nombre; private $_nombreReal; private $_nombreReal; private $_edad; private $_edad; private $_clave; private $_clave; public function getEdad() public function getEdad() { { return $this->_edad; return $this->_edad; } } public function setEdad($edad) public function setEdad($edad) { { $this->_edad = $edad; $this->_edad = $edad; } } public function getNombre() } { return $this->_nombre; } Pronto, ahora el atributo se puede consultar o } modificar no directamente, solo a través de los métodos "get / set". En este caso no se nota la Ahora se puede consultar el nombre pero no utilidad, pero pasemos al siguiente modificar, pues el atributo no es visible desde requerimiento. fuera del objeto, solo a través de los métodos públicos que vamos definiendo. Recordatorio Requerimiento 3 No nos interesa que se sepa el nombre real del Estamos usando el estándar de usuario codificación definido por la empresa Zend. Por ejemplo, los métodos y Lo dejamos como está y queda inaccesible atributos privados deben iniciar con desde fuera del objeto. “_” y todas las llaves de métodos y clases inician a la izquierda (ninguna otra más, como un if, for, etc). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 85. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 85 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimiento 4 Formalicemos: "Getter/Setter es solo un Queremos que pueda colocar una nueva clave tema de conceptos" si el usuario se la olvida, pero no saber la que existe actualmente Cuando empezamos a aprender a usar Objetos el primer error que cometemos es dejar todos Para eso, hacemos lo contrario que con el los atributos públicos, lo que permite que atributo nombre, agregamos un método "set" cualquier usuario de nuestra clase pueda hacer pero no el "get": y deshacer sin control nuestro objeto class Usuario (modificando y consultando sus valores). { private $_nombre; Generalmente nuestros objetos deberían private $_nombreReal; contener determinada información que no private $_edad; necesariamente el usuario de nuestro objeto private $_clave; debería saber, porque no conviene, o porque public function getEdad() directamente no corresponde y permitirle { acceder a la misma es aumentar return $this->_edad; innecesariamente la complejidad del uso del } objeto. public function setEdad($edad) Regla: "Evitar que el objeto muestre detalles { $this->_edad = $edad; de su implementación" } public function getNombre() Por ejemplo: si tu sabes que tu objeto { "Persona" tiene una fecha de nacimiento y return $this->_nombre; calculas su edad, no deberías poder permitir } public function setClave($clave) que alguien "de afuera del objeto" cambie la { edad, pues está relacionada con otra $this->_clave = $clave; información (fecha de nacimiento) y a partir de } ella es que se genera (calcularEdad()). } Lo correcto sería modificar la fecha de Pronto, usando simples métodos podemos nacimiento para que el propio objeto la vuelva a reforzar el diseño de nuestro objeto, calcular. restringiendo según nuestra necesidad el acceso a sus atributos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 86. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 86 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com De lo contrario, ya sería mejor que crearas un Los detalles del funcionamiento del objeto son método común y corriente, asignándole un internos, y el usuario del objeto (otro nombre claro a su acción. desarrollador u otro sistema) no debe ni necesita conocerlos. Por consiguiente ya Errores más comunes tenemos otro caso claro, el atributo "edad" no debería poder ser modificado externamente, Definir todos los "get" y "set" para todos los pero sí consultado cada vez que se necesite. atributos existentes. Es casi lo mismo que si fueran todos públicos, careciendo de utilidad. Si este fuera un atributo público sería imposible restringir una operación y habilitar Lo habitual es que esto no debería suceder, la otra. De ahí que nace el concepto de "getter cuanto más escondamos de nuestro objeto / setter", o de "métodos accesores / mejor será, pues disminuimos la complejidad de modificadores", o como muchos autores se su uso y evitamos que cambie a un estado que refieren a estos métodos especiales como no queremos, y cuando menos se sepa de "propiedades" (pero creo que puede generar cómo trabaja internamente, más fácil será confusiones con el concepto "atributo", pues poder reutilizarlo en contextos distintos muchos otros autores usan las mismas palabras (deberá ser raro que debas dejar disponible indistintamente). todo y no existan algunos que sean solo de uso interno). Si tú colocas atributos privados, estos serán solo "vistos / accedidos / usados / modificados" Otro error común es agregarle más lógica que dentro de la propia clase. Si tu quieres que asignar un valor o retornar el valor del puedan ser accedidos desde fuera de la clase, atributo. Si necesitas agregarle lógica, ya dejan debes crear métodos públicos que de ser "get / set", lo cual es mejor que internamente "accedan" a los atributos, pero cambiemos de nombre y lo dejemos con los que los dejarán "resguardados" dentro del demás métodos comunes de nuestra clase. objeto (no hay que olvidar que en un caso pueden hacer una operación u otra, no Por ejemplo: si para cambiar el nombre del necesariamente ambas). usuario, antes de asignar el valor voy a la base de datos y verifico que no exista otro igual, y Recalco, digo "nomenclatura", puesto que los luego en caso de nombre duplicado genero otro nombres de los métodos pueden llamarse como alternativo, etc, preferiría o desglosar el quieras, pero si cumplen con ambas método setNombre en varias llamadas a definiciones (get/set), cumplirá con la esencia métodos privados, o directamente crear un de la funcionalidad. El tema es que, por método nuevo que se llame cambiarNombre, convención, se tiende a reconocer así a los reflejando un proceso fuera del simple get/set. métodos que solo sirven para "hacer operaciones básicas como si trabajáramos con atributos públicos", y que además, no deben tener más complejidad que la que describo. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 87. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 87 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Nota: esto es muy a nivel personal, hay opiniones encontradas sobre tener una lógica Trata de seguir las siguientes elemental dentro de un set/get o hacerlo tan reglas extenso como necesitemos. Claramente estoy en el primer grupo. 1. Por defecto, atributos privados Como detalle, para que quede más 2. Usa métodos comunes y no getter/setter evidente y visualmente claro 3. Si no queda otra opción, usa solo getter 4. Si no queda otra opción, usa setter Como todo es convención a la hora de definir la 5. Trata de evitar getter y setter a la vez forma de trabajo en un entorno de desarrollo, (efecto "atributo público") es habitual que los atributos siempre vayan juntos al principio de la clase e inmediatamente -antes de empezar a definir los métodos- deberían estar los métodos "accesores / modificadores". Lo que se suele hacer, pues son métodos muy simples y generalmente carentes de mucha lógica (como se explica en el punto anterior), tal vez sería mejor hacerlos en una sola línea, sin indentación: class Usuario { private $_nombre; private $_nombreReal; private $_edad; private $_clave; /** getter / setter */ public function getEdad(){return $this->_edad;} public function setEdad($edad){$this->_edad = $edad;} public function getNombre(){return $this->_nombre;} public function setClave($clave){$this->_clave = $clave;} } Nota De todas formas no tomar esto más de un ejemplo, ya que el estándar oficial de codificación para PHP (el que define la empresa Zend) no sugiere en ningún momento esta práctica. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 88. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 88 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen El tema no es tan complejo, de forma genérica esta es la explicación de qué es "getter/setter" y para qué sirve y cómo se usan. También quiero destacar que a pesar de existir esta técnica, no quiere decir que deba ser usada o que su uso esté completamente permitido. Hay que entender que la POO no debería hacer uso de de los getter y setters ya que tendríamos acceso de forma directa al "estado del objeto" (la información que tienen los atributos de un objeto) y permitir el acceso o modificación genera el mismo efecto de manipulación que si fuera una operación de "corazón abierto". Nuestro objeto debería estar protegido del exterior y no permitir tener acceso directo a sus atributos, y trabajar siempre sobre sus métodos ("los métodos definen el comportamiento del objeto"). En caso de no poder hacerlo, se podría priorizar disponer de "get" (obtener valor de un atributo de forma directa) y no "set" (modificar un valor directo de un atributo), y en el peor de los casos, tener un uso muy controlado de los "set". Para más información sobre diseño OO, discusiones teóricas, buenas prácticas, etc, consultar escritos de gurúes como Martín Fowler. Quieres solicitar un ejemplo adicional? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 89. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 89 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 10 - “Cómo representar las Relaciones entre clases en UML” Definir las relaciones entre las clases es la parte medular de la POO y donde verdaderamente construimos el Diseño OO. Es importante hacer un buen diseño individual de clases, pero más aún saber qué significa cada relación, cuando se deben usar y que impacto tiene sobre todo el sistema. IMPORTANTE Aquí entenderemos por qué considero FUNDAMENTAL estar apoyado por diagramas para poder visualizar, razonar y discutir un diseño OO. Las relaciones, el significado y sus consecuencias son el corazón de la disciplina. Por ejemplo, nadie concibe enseñar Base de Datos sin empezar primero por los diagramas de relaciones DER/MER. Empecemos con las relaciones más básicas y fundamentales: “la dependencia y la asociación” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 90. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 90 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Unas buenas especificaciones incrementará la productividad del programador mucho más de lo que puede hacerlo cualquier herramienta o técnica" Milt Bryce SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 91. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 91 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com La Relación de Dependencia Todos los diagramas tienen varias interpretaciones, este en concreto nos dice Definición: “es una relación de uso entre dos que: entidades” (una usa a la otra)  La clase A depende de la clase B La relación de dependencia es cuando una clase depende de la funcionalidad que ofrece otra  La clase A usa la clase B clase. Si lo vemos del punto de vista “Cliente / Servidor” (existe una entidad que necesita de  La clase A conoce la existencia de la un “servicio” y otra entidad que lo provee), se clase B, pero la clase B no conoce la puede decir que una clase es “cliente” del existencia de la clase A (es lo que servicio de otra clase. significa el sentido de la flecha) Esta es la relación más básica entre clases y a su  Todo cambio que se haga en la clase B, vez comparada con otro tipos de relaciones, la por la relación que hay con la clase A, más débil. podrá afectar a la clase A. Representación UML Por eso también se le dice “relación de uso”, la clase A “usa” la clase B. La representación en UML es una “flecha punteada” o “discontinua” que va desde la clase “cliente” del servicio/funcionalidad hasta la clase que ofrece el “servicio/funcionalidad”. Un diagrama genérico sería: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 92. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 92 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo se traduce a código Presta especial atención en el “require_once”, ya que esta sentencia está representando la Solo existen dos situaciones posibles “dependencia” con otra clase al requerir su 1. En un método de la clase A instancio un fuente. Tomando el código fuente de una clase objeto de tipo B y posteriormente lo y siguiendo todos sus require / include uso. podemos determinar la dependencia con otras clases y reconstruir el diagrama (ingeniería 2. En un método de la clase A recibo por inversa). parámetro un objeto de tipo B y posteriormente lo uso. Por consiguiente, completemos los diagramas de ejemplo: Caso 1 – instancio un objeto B dentro de un método de A Y traducido a código será: A.php: <?php require_once 'B.php'; class A { public function mostrar() { $b = new B(); /* etc */ } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 93. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 93 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 2 – recibo por Finalmente, la “flecha punteada” representa parámetro de un método de que es una “relación débil” en contraposición a A un objeto B la siguiente relación, la “asociación”, que se representa con una “flecha continua” y representa una relación “más fuerte”. A.php <?php require_once 'B.php'; class A { public function mostrar(B $b) { echo $b; /* etc */ } } Varios detalles a tener en cuenta:  En el diagrama UML se representa el parámetro de esta forma b : B, lo cual debe ser leído en el orden variable : Tipo, pero dependiendo del lenguaje, la traducción generalmente es al revés: Tipo $variable (como se puede observar en el ejemplo con el método “mostrar(B $b)”).  Aparece por primera vez el Type Hinting (“indicando el tipo”) que es incorporado en PHP5 (imitando muchos lenguajes de tipado fuerte como Java) y que permite –sin llegar a perder el tipado dinámico- reforzar el diseño al solo permitir que ingresen por parámetro objetos del tipo que especifiquemos (ampliaremos más adelante). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 94. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 94 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com La Relación de Asociación Representación UML Definición: “es una relación estructural entre La representación en UML es una “flecha entidades” (una entidad se construye a partir de continua” que va apuntando desde la clase otras entidades) “compuesto” hasta la o las clases “componentes”. La relación de asociación es cuando una clase tiene en su estructura a otra clase, o se puede Un diagrama genérico será: decir también que se construye una clase a partir de otros elementos u objetos. Si lo codificáramos esto se representa como un atributo que es una instancia de otra clase. Esta relación se debe entender como la actividad de construir elementos complejos a partir de otros elementos más simples, y Nuevamente, los diagramas tienen varios justamente, la verdadera esencia de la POO. mensajes que nos transmiten: Por ejemplo  La clase A depende de la clase B Un auto está compuesto por un motor, un  La clase A está asociada a la clase B tanque de combustible y una antena de radio, por lo tanto tendríamos:  La clase A conoce la existencia de la clase B, pero la clase B no conoce la  un objeto Auto y como atributos del existencia de la clase A (sentido de la mismo tendríamos los objetos Motor, flecha) Tanque y Antena. Lo interesante notar aquí es que el Auto no  Todo cambio que se haga en la clase B, conoce los detalles internos de cada uno de sus por la relación que hay con la clase A, componentes, simplemente se construye a podrá afectar a la clase A. partir de ellos pero cumplen el “Principio de Ocultación”, lo cual fortalece el diseño al desconocer detalles internos que pueden obligarlo a depender fuertemente de cómo están implementados. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 95. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 95 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo se traduce a código Creando una clase A que tiene como atributo un  Lo ideal sería que en la misma objeto de tipo clase B. definición del atributo poder hacer la creación de la instancia del objeto sin A.php <?php depender de un constructor (como sucedería en Java), pero el detalle aquí require_once 'B.php'; es que PHP no soporta la creación de class A instancias en la definición de atributos, { solo podríamos hacer una asignación private $_b; directa si el atributo es un array, pero public function __construct() no crear una instancia (con “new”). Solo { podremos crear las instancias de $this->_b = new B(); } nuestros atributos en el constructor o } dentro de los métodos de la clase. $a = new A(); Varios detalles a tener en cuenta:  En el diagrama no se especifica en la clase A, en la zona de atributos, el atributo “b”, pero se puede inferir de la relación representada en el diagrama. Por lo tanto está sujeto a decisión de cada uno agregar o no más detalle en el diagrama (lo cual dependerá siempre del público objetivo del mismo).  Como no se especifica, tampoco parece decir nada sobre su visibilidad: mantendremos siempre el criterio que los atributos por defecto son siempre “no públicos”, por lo tanto por defecto son “privados” (más adelante veremos otras posibilidades). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 96. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 96 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com UML del ejemplo del Auto Auto.php <?php require_once 'Motor.php'; require_once 'TanqueCombustible.php'; require_once 'AntenaRadio.php'; class Auto { private $_motor; private $_tanqueCombustible; private $_antenaRadio; public function __construct() { $this->_motor = new Motor(); $this->_tanqueCombustible = new TanqueCombustible(); $this->_antenaRadio = new AntenaRadio(); } } $auto = new Auto(); Los comentarios sobre la lectura de las flechas y los sentidos son los mismos que en los casos anteriores:  Según el sentido de las flechas, el Auto conoce a sus componentes y los componentes no conocen al Auto.  Si los componentes cambian, afectan al Auto, ya que este está asociado a ellos, no así al revés. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 97. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 97 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Variaciones de Asociación: Ejemplos de Agregación y de Composición Relación de Agregación y Relación de Composición Se puede especializar la relación “asociación” en dos tipos más (note que las flechas siguen siendo continuas pero agrega un rombo en su inicio). Relación de Agregación “La Universidad agrupa muchos Alumnos” Es una relación de asociación pero en vez de ser “1 a 1” es de “1 a muchos”, la clase A agrega muchos elementos de tipo clase B “El círculo está compuesto por puntos” Relación de Composición Al existir una relación de vida, no se concibe que existan puntos sueltos sin estar en una Similar a la agregación, solo aporta semántica a figura geométrica la relación al decir que además de “agregar”, existe una relación de vida, donde elementos de B no pueden existir sin la relación con A. Desde el punto de vista de muchos lenguajes (como Java o PHP) esto no necesariamente genera ningún cambio en el código, pero puede ser tomado como parte de la documentación conceptual de cómo debería ser el diseño del sistema. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 98. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 98 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Ejemplo de traducción a código Ejemplo de traducción a código La forma de representar ambas variantes es Universidad.php simple y como en todos los casos, mecánica. <?php El elemento del lenguaje que por defecto nos require_once 'Alumno.php'; permite contener varios elementos es el array, por lo tanto del diagrama se desprenden class Universidad { (aunque no esté explícitamente) que private $_alumnos = array(); tendremos: public function add(Alumno $alumno) 1) Un atributo de tipo array para contener { $this->_alumnos[] = $alumno; todos los elementos } } 2) Por lo menos un método para agregar los elementos al array, que $universidad = new Universidad(); generalmente se representa con un $universidad->add(new Alumno()); simple “add” (que como siempre queda $universidad->add(new Alumno()); sujeto a variar según nuestro criterio). $universidad->add(new Alumno()); Teniendo en cuenta lo anterior, podría apuntar mi diagrama a un público que no le fuera /* * Esta universidad contiene 3 alumnos evidente su implementación, por lo tanto */ podría ser tan específico cómo: Aunque podría pecar de redundante, ya que el diagrama original ya representa toda esta implementación. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 99. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 99 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Qué relaciones se deberían Ejemplo de relación cíclica evitar? Las relaciones bidireccionales y las relaciones cíclicas, ya que la visibilidad es en ambas partes (A y B) y un cambio en una clase genera un impacto en la otra y viceversa, logrando una inestabilidad muy peligrosa. Ejemplo de cómo se representa una relación bidireccional Creo que es evidente el problema sin necesidad de codificar el ejemplo, un cambio en A afecta a ElHuevoOLaGallina.php <?php C, como afecta a C, también afecta a B, que a su vez afecta a A… y sigue. class A { Caso de Ejemplo private $_b; public function __construct() "¿Qué sucedería si tenemos una clase Curso y { otra Profesor? El profesor puede impartir $this->_b = new B(); varios cursos y un curso puede tener varios } } profesores. ¿Cómo haríamos las relaciones? ¿Dos flechas de agregación, una de Curso a class B Profesor y otra de Profesor a Curso?" { private $_a; Aquí es cuando entra la "decisión de diseño" en public function __construct() base al análisis de lo más conveniente según el { problema que queremos resolver y de evitar $this->_a = new A(); } "todo lo posible" hacer relaciones cíclicas / } bidireccionales. La sugerencia es "deberíamos optar por uno de los dos diseños" (no ambos) de acuerdo a la navegación que sea más conveniente de acuerdo a las necesidades del sistema, qué información requerirá con más frecuencia. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 100. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 100 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Si va a ser más frecuente buscar los cursos de un docente o si a partir de un docente vamos a necesitar saber sus cursos. Aún eligiendo uno u otro diseño, siempre podremos "navegar" por ambas formas, solo Confusión común que una va a costarnos más que la otra. A veces podemos cometer el error de decir "cíclicas" cuando deberíamos Si tenemos Curso -> Profesor decir "bidireccionales", en sí el efecto  Se resuelve directamente si es el mismo, solo que en bidireccional necesitamos los profesores de un curso. no hay un ciclo porque es una relación de 2 clases ("en dos direcciones") y para  Pero, para obtener de un docente hacer una relación "cíclicla" se necesita cuales son sus cursos, deberíamos por lo menos 3 clases para poder hacer recorrer todos los cursos para recién un ciclo. saber qué cursos tiene asignado. Siempre, La última alternativa debe ser optar por una relación bidireccional ó cíclica, porque aumentas problemas y costos de desarrollo. Comentario final : Imaginar cómo sería el funcionamiento de un sistema con relaciones bidireccionales y a su vez cíclicas entre varias clases… lo más parecido a un "Castillo de Naipes" ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 101. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 101 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumiendo rápidamente Por ejemplo: algunos conceptos  1 complementarios  1..* “Navegabilidad”  0..* La lectura que debe hacerse al interpretar los  3..14 diagramas es: Donde en el primer caso decimos que en A A -> B veremos siempre un objeto de B, en el segundo caso “uno o muchos”, en el tercer caso  “B no tiene idea de A” “ninguno o muchos” y el en último caso “de 3 a 14”.  “A puede invocar métodos de B, pero no al revés” Por ejemplo, podrías decir que tienes una Escuela -> Alumnos, entonces podrías agregar a A–B la flecha:  Bidireccionalidad: “A ve a B, pero en  1..N algún momento B ve a A”  0..N Primer caso, significa que en algún momento la “Definición de Roles” escuela ve 1 o más alumnos (N), pero si haces Las relaciones tienen nombre: “tiene”, el segundo caso, estás diciendo que en algún “contiene”, “fabrica”, etc. momento la escuela puede que no tenga alumnos. A -tiene-> B Imagina una relación Esposo -> Esposa, podría Y es parte de la documentación especificar los ser 1..1, ya que si haces 1..2 ya serías bígamo roles de cada relación para ayudar a su interpretación y codificación posterior. ¿Cómo nos afecta cuándo debemos traducilo a código? Que si tienes 1..1 debes controlar que “Multiplicidad” no pueda suceder (o que de error) si alguna vez no se cumple esta regla. Parte de la documentación de UML, en una relación A->B, poder especificar la cantidad de Es un elemento más que se puede agregar en objetos de B que se pueden ver en A la documentación y que aporta información a quién tiene que interpretar el diagrama y generar el código a partir de él. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 102. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 102 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Vimos cómo se representan las relaciones básicas entre las clases, cómo la dependencia es una relación más débil que la asociación, y cómo la agregación es una variante de asociación, y que la composición se diferencia de la agregación solo por “semántica”. Fundamental es entender la visibilidad entre las clases, el sentido de las relaciones, y por qué es importante que estas se den de forma acotada y medida, ya que existir flechas que salgan hacia todos lados, de forma bidireccional o cíclica, generan que nuestro sistema sea completamente inestable y con un alto costo de mantenimiento, ya que cualquier cambio en una clase generará un impacto contra las demás clases del sistema. De aquí en más se empezará a entender que aprender POO o diseñar un sistema OO no puede hacerse sin plantear un diagrama UML analizando meditadamente las relaciones que deben existir entre las clases, ya que es la única forma de graficarlas y visualizarlas con facilidad. Tranquilos, sobre estos temas vamos a ir presentado ejercicios de ejemplo con sus soluciones a partir de varios capítulos a continuación, ya que este es un tema medular ;-) Quieres bajar el código fuente de los ejemplos? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 103. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 103 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 11 - Ejercicio "Micaela, el Perro y la Escuela” Ampliemos progresivamente los ejercicios prácticos aumentado gradualmente la complejidad. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 104. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 104 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Cuando se está depurando, el programador novato introduce código correctivo; el experto elimina el código defectuoso" -- Richard Pattis SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 105. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 105 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos Se espera Partiendo como base el problema presentado anteriormente, ahora se agregan los siguientes Que el Index esté representado en los requisitos: diagramas y ser la "Clase Controladora" que inicia el sistema), y ninguna clase puede "Micaela, además de tener un perro e imprimir por su cuenta (hacer un “echo”), solo interactuar como vimos, ella va a la escuela Index (todos los métodos deben retornar datos 'Dos Corazones' junto a 5 niños más. Uno de hacer ningún tipo de impresión). esos niños es hermana de Micaela y se llama Martina (3 años), ambas son dueñas del mismo perro. Tienen un amigo que se llama Marcos (6 años) y él es dueño de un gato de muy mal Explicación: “Controladora” carácter, que si le tiran de la cola, es seguro que araña!" Se dice “clase controladora” a una clase que toma el control de la solución de un problema o Guía situación concreta desde una visión de alto nivel. Generalmente a partir de ella se crean y usan la mayor parte de los objetos involucrados en la Primero solución. - Representar las relaciones entre las clases Index, Persona y Perro. Segundo - Representar la Escuela, que debe poder contener a todos los niños de la letra. - Representar la relación de "hermano" entre Micaela – Martina. - Representar el Gato - Usar toString() (ver manual) para que cada objeto sepa cómo convertirse a "cadena de texto". - Fundamental, se hará más hincapié que el diseño y código sea KISS, cuanto más código no solicitado se encuentre, más puntos se perderán. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 106. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 106 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución La idea de cada tarea es aplicar y extender los conocimientos que se debieron haber adquirido con la lectura de los capítulos anteriores. Se define un nuevo contexto para evaluar la evolución del lector. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 107. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 107 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Errores Comunes” mundo, y recién “la visión de bosque” la tenemos cuando nos paramos sobre Estos fueron los errores más comunes que han un “index.php” (o el nombre de turno). cometido alumnos en cursos a distancia:  Olvidar representar en código las  El constructor demasiado atado al flechas del diagrama UML: hay que contexto del problema: he visto casos entender que –por ejemplo- si desde donde en el constructor de la Persona index hacemos “require_once” a 4 se agrega la posibilidad de recibir un clases, si o si, significa que hay 4 flechas “hermano”. La sugerencia es que el hacia esas clases, y viceversa, si hay 4 constructor sea siempre simple y que flechas desde Index, debemos crear 4 contenga la mínima información que “require_once” en Index. represente a la clase para crearla, como podría ser el nombre y el apellido,  Confundir desde donde hacer los tal vez la fecha de nacimiento, no “require_once”: debemos entender mucha información más. Nuestra que PHP “suma” todos los fuentes decisión luego es, si la persona al como uno solo y luego lo ejecuta, por lo crearse no cuenta con su fecha de tanto, si colocamos todos los nacimiento, ¿permito que se pueda “require_once” solo en el index, el crear? ¿O requiero esa información sistema funcionará, pero no es lo siempre? De la misma forma considero correcto. Cada clase debe mantener que definir un hermano estaría sus relaciones de acuerdo al diagrama, separado de la creación de la persona, ya que mañana funcionará en otro por lo tanto sería más conveniente que contexto y ella debe saber qué clases si tiene un hermano, poder hacer esa necesita para funcionar. Si todo está en relación con un método posterior Index, esto no representa las (agregarHermano() o setHermano(), relaciones desde la clase correcta. según lo que necesitemos hacer). Tampoco es problema que las flechas o “require_once” se repitan (el mismo  Comprender la utilidad de Index, más “_once” hace que solo tome la primera allá de lo evidente: index.php podría invocación y el resto se ignore). Por lo ser mañana admin.php, no importa su tanto deben ir desde Escuela hacia nombre, lo que importa es que ese es el Persona y desde Persona hacia sus punto de partida donde construimos la mascotas. solución a nuestro problema, implementamos nuestros  No respetar el estándar de codificación requerimientos, juntando todos los de Zend, en particular el uso de las objetos que implementamos y llaves {} para los métodos y las empezamos a hacer que interactúen sentencias internas. Las llaves inician a para que trabajen para nosotros. Esto la izquierda solo cuando es una clase o nos da una idea de que cuando un método, en ningún otro lado más. trabajamos diseñando una clase nos tenemos que olvidar del resto del SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 108. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 108 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com  No hacer “validación de tipo” (“Type  Se presentan algunos casos de hinting”): en el caso de la Escuela, al “desborde de ingeniería”. Hay que agregar Personas, validar que solo se recordar el Principio KISS, por lo tanto puedan agregar del tipo la clase debemos realizar las siguientes “Persona” y no otro, lo mismo para el preguntas: caso en que el diseño de Persona fuera “agregar” Mascotas (refuerza el diseño, o ¿Si para implementar un es más robusto ante situaciones no ejercicio tan acotado necesito tanto código, para un proyecto esperadas). real cuando más necesitaré?  Los atributos van siempre privados o ¿Podré manejar toda esa (99,99% de los casos), tanto por UML complejidad? como por código. o ¿Cumpliré los tiempos de  Auto relación Persona -> Persona: a entrega? pesar que una persona tenga elementos de tipo Persona, no hace falta en la o ¿Y si trabajo en equipo? ¿seré clase Persona agregar un require_once lo suficiente claro como para hacia Persona. que otro integrante de mi equipo pueda seguirme y  Evitar relaciones cíclicas: se vieron repartirnos todo el trabajo? ¿o diseños que planteaban que la Mascota debo hacerlo todo yo porque tuviera una colección de Dueños. En sí no entienden lo que hago? el diseño no está mal a menos que genere una relación cíclica entre las o Hacer las cosas complicadas no clases, es decir, Persona ve a la Mascota es una virtud, hacer simples las y la Mascota a la Persona (A<->B), por lo cosas complicadas debería ser tanto cualquier cambio en una clase el verdadero arte y objetivo en afecta a la otra y así sigue en ciclos. Por nuestra actividad como lo tanto, este diseño debería evitarse desarrolladores profesionales. para anular la relación cíclica (o romperla de alguna forma).  El toString es un método reservado __toString: PHP5 fija para varios métodos especiales (constructor, destructor, toString, etc) una sintaxis distinta, le agrega “__” (dos guiones inferiores) al principio del método. Por lo tanto, para que toString funcione hay que implementarlo así, de lo contrario no funcionará al hacer echo $persona; SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 109. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 109 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 1) El ejercicio busca llevar al extremo las Para no perder foco en las relaciones herramientas que disponemos entre los elementos y confundirse con todas las flechas, se omite El ejercicio busca doblar de alguna forma las intencionalmente en este ejemplo la herramientas que disponemos en la clase Index (ver ejemplo completo más actualidad para con la práctica darnos adelante). cuenta que nos faltan elementos para representar toda la realidad que tenemos ¿Cómo se probaría este diseño y delante. Por consiguiente, cuando veamos verificar que cumpla con la letra? las restantes relaciones entenderemos cómo terminar de armar un diagrama más completo. Auto-relación "Persona" 2) Tarea 2 – propuesta de diseño 1 Si tú eres "Persona" y tienes una relación con (otra) En este caso se usa la herramienta Persona, se dice que tienes una auto-relación, por StarUML y vamos a representar la lo tanto se podría representar con una flecha que relación “hermano” con un atributo sale de Persona y vuelve otra vez a la clase simple de tipo “Persona”. Persona. Como poder, se puede hacer y está permitido, pero a veces por claridad y evitar tantas Tener en cuenta en muchas veces se ven “flecha de agregación” (con el flechas, se deja solo lo necesario de lo que quieres comentar / documentar, por lo tanto si tienes un rombo en su inicio) sin la punta -> pero atributo de tipo Persona se sobre-entiende que es el significado es el mismo. una auto-relación, lo mismo, tampoco es necesario Diagrama UML (usando StarUML) en Persona hacer un require_once a Persona, ya estás en la misma clase. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 110. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 110 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Veamos primero cómo sería el código de index.php sin crear la clase para probar paso a paso toda la letra: index.php: <?php require_once 'Persona.php'; require_once 'Perro.php'; require_once 'Gato.php'; require_once 'Escuela.php'; /* Micaela tiene un perro */ $persona = new Persona('Micaela', 5); $perro = new Perro('Tito', 'blanco y negro'); $persona->setPerro($perro); /* Martina, dueña del mismo perro... */ $persona1 = new Persona('Martina', 3); $persona1->setPerro($perro); /* ... y hermana de Micaela */ $persona->setHermano($persona1); /* Marcos es dueño de un gato */ $persona2 = new Persona('Marcos', 6); $persona2->setGato(new Gato()); /* Escuela Dos Corazones */ $escuela = new Escuela('Dos Corazones'); /* ... Micaela va junto con 5 niños más ... */ $escuela->addAlumno($persona); $escuela->addAlumno($persona1); $escuela->addAlumno($persona2); $escuela->addAlumno(new Persona('Julio',5)); $escuela->addAlumno(new Persona('Martín',4)); $escuela->addAlumno(new Persona('Carla',4)); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 111. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 111 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Para poder modificar este comportamiento en Detalle importante a tener en el contexto de PHP4, habría que hacer cosas cuenta con las relaciones como cambiar la función para que retorne el PHP4 era un lenguaje donde todo era “por objeto modificado y sustituirlo por el que quedó valor” y había que especificar explícitamente fuera (así forzamos a que cambie): cuando era “por referencia”. PHP5 se pone a tono con los lenguajes POO y de ahora en más $persona = agregar_hermano($persona); todos los objetos son siempre “por referencia”, por lo que no hay que especificar nada (y en ningún otro lenguaje POO). Todo esto cambia cuando usamos por defecto ¿Qué significa esto? “pasaje por referencia” (lo que ocurre en PHP5), ya que si pasamos un objeto es la Si fuera por valor, cuando hacemos: referencia a este y no importa donde estemos, si cambia, estamos cambiando el objeto original (y único). $persona = new Persona(); Se deberá entender entonces que no es necesario retornar nada cuando modificamos agregar_hermano($persona); un objeto dentro de una función. var_dump($persona); /* Funciones */ function agregar_hermano($persona){ $hermano = new Persona(); $persona->setHermano($hermano); } El var_dump final no mostraría al hermano, ya que cuando se envió por parámetro, pasó por valor y lo que cambió fue solo eso, no el objeto original, y fuera de la función, no ocurrió nada. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 112. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 112 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Por lo tanto, el orden de la asignaciones entre Repuesta: no es necesario, la persona que los objetos no son realmente necesarias si mandamos a la escuela es la misma que manejamos correctamente el concepto de las tenemos luego, ya que es una referencia. referencias. Cualquier referencia que modifiquemos, afecta al mismo objeto del sistema. Por ejemplo: $persona = new Persona(); ¿Y ahora, cómo puedo probar el contenido de cada uno implementando correctamente los $escuela->addAlumno($persona); toString() de los objetos? $persona->addPerro($perro); ¿El perro quedó asociado a la persona que entró a la escuela? ¿Si? ¿no? ¿Si agregamos a la persona antes de asociarla con el perro, no debería primero haber agregado al perro y luego mandar a la persona a la escuela? SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 113. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 113 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com El método público toString() toString es un método público, pero que no hace falta ejecutar literalmente, ya que lo hace Todas las clases que tengan nombre (Persona, de forma automáticamente con cualquier Perro) podrían tener un toString de este tipo: operación que obligue/necesite hacer que un objeto deba comportarse como un String (“cadena de texto”). Perro.php: El único caso que podría ser más complejo sería <?php el toString de Escuela, que podría ser solo la class Perro impresión del nombre, pero si queremos que { muestre todo su contenido (que no es necesario /* … */ hacerlo en el toString, ya que lo anterior es lo justo). public function __toString() { Ejemplos: return $this->_nombre; } } - ¿Si tenemos un objeto Persona, cual sería la mínima información en texto que lo describiría? Generalmente el nombre y apellido. Así cuando necesitemos “convertir un Objeto a - ¿Si tenemos un objeto usuario, cual sería la String” (“imprimirlo”), simplemente haremos: mínima información en texto que lo describiría? Generalmente el nombre de echo $perro; usuario. Que es lo mismo decir (y funciona): - ¿Si estamos hablando de una mascota? Simplemente el nombre. echo $perro->__toString(); - ¿Si estamos hablando de una pieza de repuesto de un auto? La descripción de la misma. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 114. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 114 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Por ejemplo, para la Escuela podría ser: <?php class Escuela { private $_nombre; private $_alumnos = array(); public function __construct($nombre) { $this->_nombre = $nombre; } public function addAlumno(Persona $persona) { $this->_alumnos[] = $persona; } public function __toString() { $retorno = ''; foreach ($this->_alumnos as $alumno) { $retorno .= $alumno .' '; /* * Es lo mismo que decir * * $retorno .= $alumno->__toString() .' '; * * solo que el objeto sabe cómo convertirse en * String, tema que detecta cuando se hace * una operación de suma de cadenas * con el punto ".". */ } return $retorno; } } } Aunque de todas formas se sugiere la simplicidad, lo correcto es que la Escuela solo retorne en el toString() el nombre de la misma, y que la información sobre los alumnos sea dada por un método específico para eso. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 115. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 115 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Lo que dice el manual de Para el caso de Micaela, como es una persona, toString() diría que lo más adecuado sería (solo agrego el método nuevo): En resumen, toString() (a pesar de lo sintético del manual oficial) es: “El método reservado "toString()" es la <?php forma que todo lenguaje POO tiene para class Persona que nosotros los desarrolladores podamos { public function __toString() definir cómo convertir un objeto en "texto { plano".” return $this->_nombre . '' .$this->_apellido; } En Java es muy común solicitar una } colección de objetos de tipo Persona y luego tirarle directamente esta información a un "combo" (otro objeto de la interfaz), y este Si fuera un Usuario y no solo una Persona, tal sabrá qué información mostrar a partir que vez agregaría en el toString el id + nombre + cada objeto tiene claramente definido su apellido. toString(). En resumen: acorta el camino, se estandariza Si tomamos nuestra clase Persona y hago: una acción muy recurrente, y evita que tengamos un getNombre() ó getDefinición() o echo $micaela; similar que dependa de nosotros agregarlo. ¿Qué hace? ¿Cómo puedo imprimir esto? Por todas estas razones todo objeto debería ¿Cómo lo traduzco? tener definido siempre su toString(). El método toString sirve para eso, la regla sintáctica es que ese método solo puede retornar un String, la regla conceptual dice que ese String debe representar con muy poca información la esencia del objeto que estoy tratando de imprimir. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 116. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 116 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Agregando las relaciones que se ven desde Index Ahora bien, una vez que tenemos resuelto nuestro sistema, ¿cómo sería el diagrama UML completo con las relaciones a todas las clases que está usando? Si hiciéramos “ingeniería inversa”, deberíamos traducir en flechas por cada requiere / include de nuestro index.php y el diagrama nos quedaría así: Index está necesitando conocer a todas las clases para luego relacionarlas entre ellas (hace “new” de las clases y luego las relaciona). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 117. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 117 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Crear la clase Index a partir de la representación UML Lo más importante ver aquí, además que todo el código presentado anteriormente en el index iría en un método ejecutar de la clase Index, son cómo todas las flechas se representan de acuerdo al diagrama, y así hay que hacerlo para cada una de las clases del diseño (revisar las flechas y representarlas exactamente con un require_once). <?php require_once 'Persona.php'; require_once 'Perro.php'; require_once 'Gato.php'; require_once 'Escuela.php'; class Index { public function ejecutar() { /* Micaela tiene un perro */ $persona = new Persona('Micaela', 5); $perro = new Perro('Tito', 'blanco y negro'); $persona->setPerro($perro); /* Martina, dueña del mismo perro... */ $persona1 = new Persona('Martina', 3); $persona1->setPerro($perro); /* ... y hermana de Micaela */ $persona->setHermano($persona1); /* Marcos es dueño de un gato */ $persona2 = new Persona('Marcos', 6); $persona2->setGato(new Gato()); /* Escuela Dos Corazones */ $escuela = new Escuela('Dos Corazones'); /* ... Micaela va junto con 5 niños más ... */ $escuela->addAlumno($persona); $escuela->addAlumno($persona1); $escuela->addAlumno($persona2); $escuela->addAlumno(new Persona('Julio',5)); $escuela->addAlumno(new Persona('Martín',4)); $escuela->addAlumno(new Persona('Carla',4)); echo $escuela; } } Index::ejecutar(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 118. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 118 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Segunda propuesta de diseño Atención con la “sobre-ingeniería”, hay que evaluar si estas mejoras no son demasiadas porque el contexto podría no requerirlo. Cambios  Se cambian las relaciones de asociación por agregación en el caso que decidamos que pueden existir más de un elemento de Perros, Gatos y Hermanos (varios hermanos, varias mascotas, etc).  Se agrega una Nota UML, que sirve para agregar explicaciones (puede ser hasta pequeñas porciones de código) para entender cómo traducir a código. Generalmente lo que se tiende a explicar es el “index”, el punto de arranca para ver cómo hacer funcionar todo el sistema (ya que a veces interpretar el diagrama de clases no es tan obvio). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 119. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 119 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagrama UML Nota Se omite la traducción de UML a PHP por considerar que su implementación a esta altura es simple y haría extremadamente extensas las explicaciones con código que ocupa decenas de páginas, cuando mostrando las principales clases nos enfocamos en lo importante de la solución. De todas formas puedes entrar a http://usuarios.surforce.com y obtener los fuentes completos y explicados de todo el libro. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 120. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 120 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Siempre se pueden plantear más de un diseño y esto quedará a discusión del equipo de trabajo y ajustándose a un contexto determinado. Aquí se plantean un par de diseños que no necesariamente son “la única solución posible” y se busca extender la comprensión de los temas tratados hasta el momento. Lo fundamental de este ejercicio es comprender:  Las distintas relaciones entre clases y su representación en código  Reafirmar que los objetos pasan siempre por referencia y no se necesita ser retornados o en determinados casos, ni siquiera un orden específico en sus asignaciones, ya que siempre estamos tratando con una referencia al mismo objeto (no copias).  La importancia del “index” como concepto de punto de partida de resolución del problema general.  El uso correcto del toString(), más allá de lo sintáctico, cual es el concepto que debemos tener en cuenta a la hora de definirlo. ¡Cualquier duda, envía una consulta! ;-) Crees que al capítulo le faltó algo? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 121. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 121 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 12 - Ejercicio "La Escuela y los coches escolares" En este ejercicio observaremos cómo se van incrementando las relaciones entre las clases y cómo una clase se compone de varias otras clases y que las clases externas no necesariamente tienen que conocerlas. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 122. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 122 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos "Tenemos una escuela que está ubicada en Ignacio Media 1212 y cuenta con 3 coches escolares para transportar a los niños de su casa a la escuela. Cada coche puede llevar como máximo a 5 niños y tienen un barrio/zona asignada. Existe un conductor por coche y un ayudante, y cada vez que un niño sube a la camioneta se le pregunta su nombre como forma de control. Para seguridad de la escuela y de los padres, se desea poder saber en todo momento el contenido de niños de todas las camionetas, el contenido de niños de una camioneta en particular y poder consultar por un niño en particular y saber en qué camioneta está" Guía Empezar a hacer un diagrama UML que represente esta realidad y posteriormente realizar en index.php lo que se solicita en la letra que debe hacer el sistema:  Saber el contenido de todas las camionetas  Saber el contenido de una camioneta  Poder buscar a un niño y saber en qué camioneta está  Representar como Personas al conductor y al ayudante  El diagrama UML no debe tener información de tareas anteriores (no va ni perro, gato, etc) Entender que desde index.php es el lugar "donde los padres consultarían esta información" (no representar con clases a los padres), por lo tanto desde ahí se debe preguntar a la escuela y esta devolver la información, nunca a un coche de forma directa. Nota: se debe usar solo lo visto hasta el momento en los capítulos anteriores. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 123. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 123 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución Este ejercicio vuelve a poner foco en el tema  Dificultad para determinar cuota de (fundamental) de las relaciones entre clases y la responsabilidad de cada uno de los objetos importancia de entender al ”objeto” como relacionados: cuando diseñamos una clase, “unidad de trabajo” sin desarmarlo de forma siempre deberíamos pararnos en ella y innecesaria. preguntar “¿Cuál debería ser su responsabilidad? ¿qué no debería hacer y sí Excepciones: cómo aún no disponemos de la pedirle a otra clase que haga (porque es herencia para estos ejercicios se tomarán como responsabilidad de otra clase)?”. Si hacemos válidos diseños con clases específicas más allá un diseño de Escuela con Camionetas que de Persona (Niño, Ayudante, Conductor, etc). tienen Pasajeros que a su vez cada uno “Errores Habituales” tiene un nombre, la solución directa debería ser: La mayoría de los alumnos al llegar a este nivel los errores fueron pocos, principalmente por o El “Padre” le pregunta a la descuidos, otras por subestimar los Escuela “¿Dónde está mi requerimientos (no leerlos con atención) y niño?” (pregunta por su pensar que los requerimientos solicitados no nombre, ya que quiere saber podían ser implementados (como buscar el niño donde está “la instancia”). y saber su coche): o La Escuela no lo sabe  Existieron diseños que implementaban una directamente, tiene que clase Camioneta, pero tenía como preguntarle a todas las atributos camioneta1, camioneta2 y camionetas y hacer la misma camioneta3, lo cual no es correcto. Se pregunta que le hicieron los define una clase Camioneta y luego una padres: “¿Dónde está el niño instancia para cada una de ellas, a lo sumo, X?” contendrá un atributo “alumnos” para almacenar sus pasajeros. o La camioneta está en similar situación que la Escuela, solo  Confusión en el UML al definir el tipo puede recorrer sus pasajeros y cuando debíamos armar las colecciones de preguntar uno por uno cómo se objetos: en algunos casos usaban llama hasta que alguno colCoches:Coche, cuando en realidad el tipo coincida. Evidentemente el es Array (que sí contendrá dentro coches). Pasajero debe poder decir cómo se llama. o Luego, se retorna una referencia al objeto Niño o al objeto Camioneta (según sea la necesidad y nuestro diseño). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 124. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 124 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com  No diferenciar cuando usar setAlgo(objeto)  Parámetros/métodos/atributos no y addAlgo(objeto): pensar que el primero descriptivos o abreviados (UML): he visto caso es cuando asocio un objeto con otro y casos en donde se documentaba en el segundo caso cuando puedo “agregar” buscarPersona(n:String):Persona, donde el varias asociaciones (de una a muchas “n” no se entiende con claridad a qué se asociaciones). refiere. No ahorren caracteres, es mejor dejar claro con el nombre del parámetro a  Uso de tipo Object y no uno concreto qué nos referimos. No siempre es mejor (como ser Persona, Coche, etc): a pesar que documentar comentando “de más” un en todo lenguaje 100% Orientado a Objetos código o un diagrama; si hacemos las cosas “todo objeto hereda de un objeto llamado detalladas se entenderán directamente sin Object”, no se aplica en nuestros problemas “anexos”. Una variable, atributo, no definir el tipo concreto y dejar uno parámetro, método bien especificado se genérico de tipo “Object” auto-documenta, no necesita un comentario.  Desarmar los objetos, retornar valores y no objetos: en algunos casos he visto que si se  Los fuentes PHP deben evitar el tag de buscaba una persona se retornaba un String cierre de PHP: el estándar solicita esto, ya que podría ser el nombre del objeto. que es casi histórico que PHP requiera Sugerencia, acostúmbrense a mantener el apertura y cierre de tag. Se argumenta que criterio que nuestra “unidad” debería ser también evita muchos errores de caracteres “un objeto”, por lo tanto retornemos ocultos en la última línea. A menos que lo objetos y no los desarmemos. Si buscamos necesites para embeber PHP/HTML, no una persona a partir de un nombre que nos cierres con el tag ?> pasaron (String), en vez de retornar un  Las variables del lenguaje null, false, true Boolean (true = encontrado), retornar el van siempre en minúsculas: otro error que objeto encontrado o de lo contrario null. cometo, ya que se pueden definir tanto en mayúsculas como en minúsculas, y siempre las entendí como “constantes” y estas deben estar en mayúsculas. Esto último no es correcto, deben ir siempre en minúsculas (estándar Zend). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 125. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 125 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Comentarios Generales”  La búsqueda se hacía directamente con el objeto a encontrar: no necesariamente quiere decir que esté mal, pero quiero recalcar todas las alternativas posibles. a. En la mayoría de los casos se hace desde la escuela un buscarAlumno($alumno):Coche, y justamente el alumno es el que se pasa por parámetro. Se podría hacer una variante más genérica como preguntar por el nombre y retornar la referencia del coche con el niño dentro (una forma de saber en qué coche se encuentra), o en otra variante si simplificamos, una búsqueda por solo el niño (retorna Niño) con solo ingresar su nombre. b. Otra posibilidad crear un “objeto parámetro”, una instancia vacía de Niño y donde los parámetros que se carguen sirvan para hacer la búsqueda del niño. Por ejemplo, crear un niño con solo el nombre asignado, o si quisiéramos, asignaríamos la edad para que la búsqueda la haga por nombre y edad a la vez.  Para el Coche Escolar definir una constante en la clase LIMITE_CAPACIDAD = 5: esto es una técnica de refactoring que se llama “eliminar los números mágicos" y ayudar a documentar sin necesidad de agregar comentarios de más (un buen código es el que no necesita comentarios para explicarse). class CocheEscolar { private $_colAlumnos = array(); const LIMITE_CAPACIDAD = 5; public function estaLleno() { return count($this->_colAlumnos) >= self::LIMITE_CAPACIDAD; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 126. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 126 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Navegabilidad Navegabilidad se le dice al camino que debemos hacer para obtener la información necesaria a partir del diseño de los objetos del problema y sus interacciones. Ya vimos que lo más natural es pensar Escuela -> Coche -> Niño, pero existen alternativas y ninguna es menos válida que la otra (más si el recorrido entre clases ayuda y no dificulta extraer la información que necesitamos). Una alternativa: cambiar la “navegabilidad”  La escuela “conoce” a los niños  Los niños “conocen” a sus camionetas Por lo pronto este diseño permite fácilmente obtener un niño y preguntarle ¿cual es su camioneta?. Si no hubiera ninguna flecha que se comunique con las camionetas deberíamos pasar por los niños para hacer cualquier cosa que requiera de las camionetas. ¿Cual es mejor? Depende de la información que estamos buscando que el sistema deba procesar, ya que según el caso una ruta nos será más conveniente que la otra y la razón la debemos decidir nosotros. Consejo No debemos tener miedo de optar por una u otra navegabilidad, es completamente normal tener que hacerlo, no existe una única navegación posible y es fundamental ajustarla para obtener el acceso óptimo a las clases. No es sano quedarnos con una navegación que nos parece más “natural” pero que nos complique a la hora de extraer o encontrar los objetos que necesitamos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 127. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 127 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo deberían ser las búsquedas Si estamos hablando de Escuela y Coche, y suponemos que el dato es la matrícula, Debemos mantener el foco en que para un deberíamos hacer: sistema “Orientado a Objetos” la unidad de trabajo son siempre “objetos”, por lo tanto para la búsqueda de un Alumno, si lo $cocheEncontrado = $escuela->buscarCoche('123456'); encontramos, debemos retornar la instancia del objeto, de lo contrario retornamos y dentro del método hacer un foreach que “null” (como estándar de “no encontrado”). pregunte por ese dato, si lo encuentra, lo retorna. Repasando cómo funciona Si se agrega desde A la clase B, simplemente es: $a->agrego(b); Y si se necesita retornar la clase B desde A, es simplemente $claseB = $a->retornoB(); Ya que internamente una vez que se encuentra la clase B del array de la clase A, simplemente se devuelve una referencia con un “return” (el objeto sigue siendo único, pero ahora hay dos referencias al mismo objeto). Si es un coche, deberían preguntar en el método de búsqueda un dato que permita buscar dentro del array, y lo que debemos hacer es preguntar a cada instancia por esa información. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 128. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 128 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagrama UML SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 129. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 129 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen En este ejercicio podemos observar las relaciones entre las clases y cómo se van componiendo unas clases a partir de otras, como también que no es necesario saber o preguntar por un “id” como si fuera una base de datos para obtener un objeto de terminado, no existiendo necesidad ya que todos los objetos de por sí son únicos, aún si son de la misma clase. Desearías que se ampliara este capítulo? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 130. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 130 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 13 - Ejercicio “Implementar diagrama de diseNo UML” Daremos vuelta la dinámica de los ejercicios y ahora recibimos un diagrama UML y debemos interpretarlo y codificarlo. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 131. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 131 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos A partir del diseño UML presentado en la solución del ejercicio anterior, traducir "exactamente" a código PHP. "No subestimar el ejercicio" Debemos cuidar al detalle cada traducción de UML a PHP, a esta altura no pueden haber errores. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 132. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 132 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución Aquí vemos que lo que podría ser un ejercicio repetitivo y simple para muchos, gran cantidad de alumnos en los cursos a distancia falló en representar correctamente las relaciones (lo más importante) y posteriormente traducir sin errores toda la información vertida en el UML. Se esperaba Que no se creara desde index dependencias si no estaban representadas en el diagrama: como estaba planteado el UML, no había relaciones con Ayudante, Conductor y Casa. La idea era tentarlos, pero que finalmente resolvieran que crear Ayudante y Conductor solo era un problema de CocheEscolar y que Casa era un problema de Niño. Aunque incluyendo todas las clases desde Index se tenga “técnicamente” acceso a las mismas (porque PHP “suma” todas las clases y las ejecuta como un único fuente) no se ajusta al diseño UML hacer uso de esas clases. Por lo tanto, y siguiendo el diagrama de relaciones, Index solo debe tener relación directa con las clases que están definidas en las flechas y así el resto de las relaciones (más adelante veremos en los casos muy específicos que esta situación podría cambiar). Index solo conoce a “A”, no conoce ni a “B” ni a “C” Index -> solo require y usa solo “A” “A” -> solo requiere a “B” y usa solo “B” “B” -> solo requiere a “C” y usa solo “C” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 133. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 133 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Qué sucedería si se están usando mal las relaciones? Por lo tanto, para verlo de forma gráfica, El diseño es frágil y al reusar las clases en otros tenemos la siguiente visibilidad contextos darán error al no tener el require_once correspondiente para poder encontrar los fuentes necesarios. Por ejemplo, si desde Index usamos la clase “B” (que técnicamente su fuente está disponible porque lo incluye “A”) y mañana “A” cambia su diseño interno y decide no usar más “B” y usar de ahora en más “C”, ¿cómo nos afectaría? Desde Index Si las relaciones están mal implementadas, en este caso los cambios internos de “A” afectarán a Index porque conoce directamente a “B” (y lo usa), mientras que si se hubiera respetado el diseño, Index solo conocería “A” y baja enormemente las probabilidades que este cambio le afecte directamente. Desde “A” Aunque la probabilidad existe, esta es menor al no conocer sus componentes internos ni depender de ellos de forma directa (de todas formas, volvemos al punto inicial, quien armó el diseño UML especificó las relaciones de esta forma con un objetivo específico). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 134. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 134 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Comentarios adicionales  Se podían hacer variantes para estas clases que no se ven desde Index, crear todo a partir de información que llega a los constructores o agregar métodos set / get para cargarlos (pasando solo datos, no instancias).  Cabe acotar que de todas formas, aunque pasemos solo los datos, teóricamente estamos pasando un “objeto desarmado” (por decirlo de alguna forma). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 135. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 135 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Errores habituales  Lo más importante y lo medular del  “include” no es lo mismo que ejercicio: a pesar que hagamos un “require”: el primero da un warning y “require_once” de todas las clases que sigue, el segundo falla y no continúa necesitemos desde el index y todo nos (“requerir” es más fuerte, nuestra clase funcione, no quiere decir que esté bien. no puede continuar si le faltan sus Cada require_once debe respetar las partes). flechas, de lo contrario las clases cuando sean reusadas y no estén  Omitir el Index por index, o usar dos, ejecutando desde el index, no index.php e Index.php: tengan en funcionarán por la falta de sus cuenta para el último caso que en dependencias/asociaciones. Eso son las Linux/Unix funciones, pero en Win son flechas, aunque las inclusiones se archivos duplicados y se sustituyen repitan (como Escuela -> Niño, Coche - entre sí. >Niño) cada clase debe saber sí o sí de quién depende y eso se representa con un require_once por clase que deba representarse.  Una convención que definimos al principio es que por nuestro estándar web es requerido contar con un index.php, y que nosotros lo íbamos a presentar en el UML como una clase, pero que físicamente era el único archivo en minúsculas (para que nuestro navegador lo encuentre).  Debemos hacer “require_once” y no “include” o “require” solos: si se requieren dos veces una clase, con “_once” solo trae en el primer intento, en los otros casos da error por repetir la definición de una clase. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 136. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 136 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Consejos  Para simplificar la creación de múltiples instancias, muchas veces se omite la variable temporal que luego es asignada a otro objeto (esto se ve mucho en Java, ya que ayuda a disminuir un poco el exceso de verborragia y kilómetros de código): Ejemplo $niño15 = new Niño('alfredo beltran','Girasoles 7453'); $escuela->addAlumnos($niño15); Simplificación $escuela->addAlumnos( new Niño('alfredo beltran','Girasoles 7453') );  Aprendan a usar la conversión de tipos: en vez de hacer esto para convertir a texto: return $this->getMatricula().""; cambiar por return (string)$this->getMatricula(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 137. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 137 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagrama UML SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 138. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 138 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Ejemplo codificado index.php <?php require_once 'CocheEscolar.php'; require_once 'Nino.php'; require_once 'Escuela.php'; abstract class Index { public function ejecutar() { $escuela = new Escuela('Dos Corazones','Ignacio Media 1212'); $coche1 = new CocheEscolar('Barrio1','Matricula1','Conductor1','Ayudante1 '); $coche1->addNiño(new Niño('Micaela', 'Direccion1')); $coche1->addNiño(new Niño('Martina', 'Direccion2')); $niñoEncontrado = $coche1->buscarNiño('Micaela'); } } Index::ejecutar(); Ejemplo de cómo sería la creación interna de un objeto, sin necesidad que esté creado en el exterior para luego recibirlo por parámetros: Nino.php: <?php Importante require_once 'Casa.php'; Prestar especial atención cómo se class Niño corresponde la flecha del diagrama { UML con el require_once de la clase. private $_nombre; private $_casa; public function __construct($nombre, $direccion) { $this->_nombre = $nombre; $this->_casa = new Casa($direccion); } public function getNombre() { return $this->_nombre; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 139. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 139 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Queda en evidencia que no se pueden subestimar los conocimientos ni la letra de ningún requerimiento. A pesar que podría parecer un ejercicio rutinario en los cursos existieron dudas en la mayoría de los trabajos. Tan importante como hacer los diagramas es aprender a recibirlos e implementarlos. Es muy habitual que si trabajamos en una empresa de gran tamaño sea de todos los días trabajar con diagramas diseñados por un “Arquitecto de Sistemas”. Algún diagrama no se entendió? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 140. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 140 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 14 - Ejercicio “Sistema para empresa que realiza encuestas” Un ejercicio más complicado en las relaciones y en la interpretación de los requerimientos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 141. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 141 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos Una empresa que realiza encuestas necesita implementar un sistema que cumpla con los siguientes requerimientos: 1. La empresa registra primero a las personas que van a contestar la encuesta 2. Posteriormente se le asigna una encuesta a la persona; existe una encuesta para cada sexo. 3. La encuesta está compuesta por varias preguntas 4. Se requiere saber en todo momento cuales preguntas fueron respondidas 5. Y si estas fueron correctas o no 6. Finalmente, tener un resumen del resultado de cada encuesta. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 142. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 142 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución Requerimientos presentados El foco de este ejercicio sigue siendo la resolución de las relaciones, pero ahora “Una empresa que realiza encuestas necesita agregando nuevas dificultades (tratando de implementar un sistema que cumpla con los acercarnos a la realidad): un contexto más siguientes requerimientos: confuso (no es resoluble fácilmente y de forma tan directa), muchas posibles soluciones y con 1. La empresa registra primero a las personas que van a contestar la errores en los requerimientos. encuesta 2. Posteriormente se le asigna una La pregunta es: encuesta a la persona; existe una ¿Cómo lo resolverán? ¿Mantendrán el foco en encuesta para cada sexo. 3. La encuesta está compuesta por varias la simplicidad? ¿En “dividir y conquistarás”? preguntas ¿discutirán los requerimientos? 4. Se requiere saber en todo momento cuales preguntas fueron respondidas 5. Y si estas fueron correctas o no Posibles dificultades Finalmente, tener un resumen del resultado de  Cómo armar las relaciones entre la cada encuesta” Empresa y sus componentes Requerimientos Erróneos  Qué debe verse desde el exterior (que Primer dificultad, el punto 5 no corresponde lo representa nuestro Index) con el contexto, una encuesta no es un examen,  Cómo registrar una encuesta y las no tiene preguntas correctas o incorrectas, el respuestas a las preguntas sistema solo debe registrar las respuestas para poder analizarlas. También se podría pensar  Cómo manejar requerimientos que fuera una encuesta “cerrada” donde hay ambiguos y/o erróneos múltiples opciones ya definidas (1-5), pero nuevamente, no tenemos una “correcta”. Simplemente un poco de “ruido” ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 143. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 143 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Muchos Diseños Posibles Un posible problema es tratar de hacer un sistema complejo de primera: “Un sistema complejo que funciona resulta invariablemente de la evolución de un sistema simple que funcionaba. Un sistema complejo diseñado desde cero nunca funciona y no puede ser arreglado para que funcione. Tienes que comenzar de nuevo con un sistema simple que funcione.” – John Gall Un enfoque es armar los objetos como elementos independientes (casi olvidándose de su entorno) y luego ver de “jugar” con los objetos haciendo que se comuniquen entre ellos (“el objeto A le pide información al objeto B, etc.”). Por lo tanto, sin importarnos ahora si todo se ve desde Index, el primer planteo podría ser el siguiente: 1. Crear las clases con sus atributos a partir de los requerimientos 2. Relacionar las clases según lo que necesitamos cumplir de acuerdo con los requerimientos. 3. Agregarle los métodos a cada Clase según la responsabilidad que detectamos debería tener cada una y sus relaciones con las demás clases de la solución. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 144. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 144 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Paso 1 – “Crear las clases y atributos” A partir de los requerimientos podemos distinguir todas estas entidades y por lo menos los siguientes atributos:  “Persona tiene Sexo”  La pregunta tiene –por lo menos- que tener un texto.  La respuesta tiene –por lo menos- que registrar el texto que responde la Persona. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 145. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 145 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Paso 2 – “Relacionar las clases” “La empresa registra primero a las personas que van a contestar la encuesta” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 146. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 146 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Posteriormente se le asigna una encuesta a la persona; existe una encuesta para cada sexo” La asignación es simplemente una relación entre una persona y una encuesta, que exista una para cada sexo en sí no se representaría a través de las relaciones en el diagrama, solo es una regla a tener en cuenta (que hay que documentar) a la hora de crear Encuestas. Si tengo 2 encuestas, preguntaré cual es el sexo de la persona y le asignaré una u otra. Para este ejercicio no aporta nada implementar esta situación. También se asume que según los requerimientos, solo hay una encuesta posible por persona, por lo tanto no manejamos la posibilidad de tener varias encuestas y crear una “agregación de encuestas” desde Persona. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 147. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 147 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “La encuesta está compuesta por varias preguntas” En esta situación podríamos llegar a documentar que las preguntas no tienen sentido de existir si no están relacionadas con la encuesta. De todas formas, se pueden dar varios contextos, como por ejemplo que la Empresa sea la encargada de crear preguntas y tener un conjunto disponible (“pool de preguntas”) para luego seleccionar algunas para una encuesta (con la posibilidad de reusar entre encuestas). Por ahora no compliquemos el diseño, optemos por una solución más simple (siempre hay tiempo para complicarlo). “Se requiere saber en todo momento cuales preguntas fueron respondidas” Aquí tal vez es lo más complicado de ver y pueden salir varios diseños posibles para registrar las respuestas. Pensemos simple, tenemos una persona, una encuesta y por cada persona tenemos que registrar sus respuestas… ¿y si asociamos por cada respuesta a qué pregunta corresponde? (no tenemos que preocuparnos a qué encuesta corresponden ya que la Persona ya lo sabe de antemano). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 148. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 148 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com También podemos decir que las respuestas no deberían existir si no existe una asociación con la Persona (composición). ¿Quién debería crear las Encuestas? ¿La Persona o la Empresa? Tiene más sentido que sea responsabilidad de la Empresa conocer a sus encuestas y crearlas. ¿Quién debería crear las Preguntas? ¿La Empresa o la propia Encuesta, serán las preguntas un problema interno y la Empresa solo pasarle la información para crearlas? ¿Index, qué debería conocer? En primera instancia haremos que conozca a casi todas las clases sin ningún pudor (dije “casi”, no “todas”). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 149. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 149 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Receta de cocina” 5. Por cada Pregunta simulo una respuesta hipotética de una persona, por lo tanto Definir Index: ¿qué necesitamos para armar el registro en la Persona qué pregunta sistema? estoy respondiendo y mi respuesta 1. Creo la Empresa (recordar, la persona ya tiene asociada a qué encuesta corresponde las 2. Podemos decidir que crear una respuestas y las preguntas, solo encuesta y sus preguntas es tendremos una encuesta por persona). completamente problema de la Empresa, por lo tanto cuando se cree la 6. Hacer un resumen de las preguntas que empresa ya existirá una encuesta con fueron respondidas, para ello hay que sus preguntas. preguntarle a la persona qué preguntas respondió. Si fueran muchas personas 3. Creo a la Persona y le pido una Encuesta se le puede pedir a la Empresa que a la Empresa y se la asigno a la Persona recorra a las personas y le pregunte a (para poder ubicar a una encuesta cada una lo mismo. determinada se le agrega un atributo “nombre”). 4. Posteriormente solicito las preguntas de la encuesta y las recorro SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 150. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 150 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “El código” index.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 151. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 151 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Empresa.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 152. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 152 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Encuesta.php Pregunta.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 153. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 153 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Persona.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 154. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 154 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Respuesta.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 155. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 155 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Index creado a “prueba y error” Si se hicieron todas las relaciones y a “prueba y error” se creó la clase Index y no se sabes cómo definir correctamente las relaciones, se puede simplemente buscar todos los “new” y estos representarán todas las dependencias de este contexto. ¿Qué sucede con las otras clases que uso pero que no creo de forma directa? Sí, de alguna forma dependes de ellas, pero de forma “indirecta”, fue la clase responsable de esos componentes que nos entregó sus elementos internos. Por ejemplo: 1. $encuesta = $empresa->getEncuesta($sexo); - La empresa nos entregó un objeto Encuesta, pero en realidad nosotros desde index dependemos de la Empresa. Perfectamente podríamos desarmar el objeto entregado y retornar solo datos, sin conocer los objetos internos (tema sujeto a criterios y discusión). 2. $preguntas = $encuesta->getPreguntas(); - Para empeorarla aún más, la encuesta nos entrega un array con objetos de tipo Pregunta. Nuevamente, la relación es indirecta, la encuesta, para facilitar la operación de procesar preguntas nos entregó varios objetos Pregunta. Resultado final, Index en este diseño dependería explícitamente de: require_once 'Empresa.php'; require_once 'Persona.php'; require_once 'Respuesta.php'; SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 156. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 156 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Finalmente, el diagrama UML de diseño posible para nuestro problema podría verse así (enfocado a las relaciones generales de las clases): SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 157. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 157 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Como otra opción, un diagrama con absolutamente todos los atributos y métodos, aún si estos se interpretan de las relaciones (de todas formas se omiten los toString por considerarlos triviales en este caso). Perfectamente se podría armar un diseño que desde Index tenga una flecha de dependencia con todas las clases del diagrama y crear libremente y de forma directa todo y luego relacionar objetos entre ellos. Para este diseño se trató de evitar (dentro de lo posible) que para usar esta solución las “clases clientes” deban conocer todos los componentes involucrados (Index en este caso). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 158. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 158 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Se deja abierto el tema a criterio y discusión del alumno para determinar en cada caso cual sería la mejor solución partiendo de las siguientes reflexiones:  Es mejor que las clases conozcan lo menos posible de los componentes de otras clases a las que usa.  Tampoco es bueno complicar un diseño por intentar esconder absolutamente todas las clases e intentar que exista una única relación contra una sola clase (por poner un ejemplo), ya que esto dificultaría el trabajo de relacionarlas (es mucho más simple relacionar objetos que tratar datos directamente, de la misma forma, intentar evitar retornar un objeto interno cuando en realidad deberíamos usar siempre “objetos de alto nivel” como unidad).  A pesar que enviemos los datos por parámetros y no un objeto ya creado, “conceptualmente” esos datos son “el objeto”.  Cada vez que una clase tiene un “new” de otra clase, indudablemente hay una flecha que sale hacia esa clase y tiene que haber un correspondiente “require_once” que represente en el código esta relación. “New” y “require_once” van juntos, siempre. “La perfección es enemigo de lo bueno”, no existe un único diseño y no hay solo “bien” o “mal”, todas las soluciones dependen del contexto concreto y qué alcance se le busca dar. Dudas? Espero tu consulta! ;-) Necesitas el fuente completo de los diagramas UML? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 159. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 159 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 15 - “Herencia, Interfaces y Polimorfismo” Luego de haber conocido las relaciones más elementales de la POO (dependencia y asociación) y sus variantes (agregación y composición), empezaremos a conocer dos nuevas relaciones: la herencia y las interfaces. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 160. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 160 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com La herencia es una de las relaciones donde más errores conceptuales se comenten, principalmente porque es fácil visualizar el “reuso mecánico de código”, lo que lleva a “heredar por el simple hecho de disponer de código”. Las “interfaces” son las “grandes desconocidas” en el mundo PHP lo que hace que generalmente los programadores directamente no las usen, pero lamentablemente se pierden de una gran herramienta que es fundamental para poder implementar buenas soluciones de diseño. Finalmente un tema que va anidado a la herencia y las interfaces es el “polimorfismo”, considerado “el patrón estratégico más importante de la POO”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 161. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 161 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com La Herencia Metáfora: como en la genética, un padre hereda a su hijo determinadas características Definición: “es una relación de parentesco que podrá usar a su favor o en su contra. Todo entre dos entidades” (una es padre de la otra, lo que esté en su contra será culpa de nuestro una es hija de la otra) diseño, de cómo habremos hecho al padre y de Antes de abordar lo “mecánico de la herencia” cuanta información en exceso dejamos que quiero destacar lo resaltado : llegue a sus hijos. Parentesco. No puede existir herencia si no existe alguna relación “familiar” entre ambas entidades. Uno de los peores errores que se puede cometer -y que demuestra la falta de conocimientos en Objetos- es usar el mecanismo de la herencia con el único objetivo de “reusar código” de otra clase. A partir de estos errores no hay sistema que pueda ser bien implementado si todos heredan de clases por el simple hecho de querer usar sus funcionalidades. “La herencia no se debe aplicar de forma mecánica, si no hay una relación literal y coherente de padre-hijo, la herencia no es aplicable” Ya hemos visto en el documento anterior que a través de una relación de dependencia se puede hacer uso de funcionalidades de otras clases y a través de la asociación construir objetos más grandes y complejos, sin necesitar siquiera de conocer sus mecanismos internos de funcionamiento (en otras palabras, “sin conocer su código”). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 162. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 162 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Representación UML La representación en UML es una “flecha continua” que va desde la clase “hija” hasta la clase “padre”, similar a la relación de “asociación”, pero con la diferencia que termina con una punta en forma de triángulo. Nota: entender la diferencia de las flechas: si es punteada (“no continua”) la relación es más débil que una “flecha continua”. Por lo tanto la Herencia es una relación igual de fuerte que la asociación, pero más fuerte que una relación como la “dependencia” (“línea punteada”). Un diagrama genérico sería: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 163. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 163 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo se traduce a código Un ejemplo podría ser que la clase Persona tiene atributos privados nombre y apellido, el Se pueden hacer varias lecturas: constructor del Padre donde carga estos datos 1. Todos los atributos y métodos se es público, de la misma forma que el toString, heredan del Padre al Hijo, pero… por consiguiente la clase Hijo podrá construir el objeto, cargarlo con su nombre y apellido y 2. Los atributos y métodos que son de desplegar sus datos cuando haga un echo de tipo “público” (public) o “protegido” Hijo, todo, sin acceder directamente a los (protected) son visibles directamente atributos de Persona (porque son privados) desde el Hijo (en el caso particular de pero sí pudo hacer uso de ellos a través de “público” son visibles de todos lados, métodos públicos o protegidos desde la clase incluyendo desde el exterior del Hijo y que fueron heredados de su padre. objeto). Por consiguiente, veamos algunos ejemplos 3. Los atributos y métodos que son de reales: definiremos una clase muy genérica tipo “privado” (private) se heredan del llamada Persona que usaremos luego para crear padre a su hijo pero no son “visibles” de distintas clases un poco más concretas y forma directa, solo se podrá hacer a particulares, que se basarán siempre en esa través de métodos del padre que sean clase. Aquí hay un claro reuso de código, ya que públicos o protegidos. todas aprovecharán lo que ya tiene definido Funcionalmente hablando podríamos decir que Persona, pero también es claro que existe una un método público “saludar” del padre que su relación de parentesco con sus hijos (“no se hijo hereda se ejecuta de la misma forma que si hereda por el simple hecho de necesitar acceder el hijo lo hubiera implementado él mismo, solo al código”). que el código se encuentra “guardado/almacenado” en el padre. Más información: Si hacemos un var_dump de un objeto hijo veremos la estructura interna del objeto y Manual de PHP, sección Visibilidad todos sus atributos y métodos privados, pero si intentamos usarlos normalmente no podremos visualizarlos, pero siguen estando ahí. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 164. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 164 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 1 –Usuario hereda de Persona Y traducido a código será: class Persona { private $_nombre; private $_apellido; } class Usuario extends Persona { } Presta atención, esta herencia no hace nada más que definir que un usuario es, además de tipo “Usuario”, de tipo “Persona”, pero como no hay atributos o métodos “no privados” (public, protected), no tiene acceso directo (“no es visible”) a lo que es “privado” en su Padre. A pesar que es un “mal padre” (chiste), el usuario es ahora de dos tipos, por consiguiente un “Type Hinting” (validación de tipos) que filtre personas aceptará al usuario porque “el Usuario es una Persona”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 165. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 165 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “El Usuario es una Persona” Si la Persona estuviera completa (con constructor y toString), este código funcionaría sin problemas en la clase Usuario, ya que heredaría de forma automática el constructor y el toString de su Padre, y usaría los atributos privados del Padre que el hijo tiene acceso a través de los métodos públicos o protegidos (según el caso). Usuario será aceptado sin ningún problema por el “Type Hinting / Validación de Tipo” reconoce al usuario como un tipo de Persona, lo cual es válido y permite su ingreso al método “imprime”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 166. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 166 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 2 –Persona agrega un constructor En este caso tendremos un método construir que es público, por lo tanto podemos usarlo desde la clase “hija” de forma automática. Hay que prestar especial atención que en PHP el constructor del padre no se ejecuta de forma automática cuando el hijo define su propio constructor, por lo tanto hay que invocar de forma explícita el constructor del padre. Repasando: si el hijo no define su constructor, igual que sucede con el toString, el destructor, etc, estos serán heredados de su Padre y sí son ejecutados de forma automática. Si el usuario define su propio constructor: Aquí, la clase usuario visualiza el método público de su padre, pero no ve directamente los atributos privados, pero, como ahora “Usuario es una Persona”, aunque no podamos “manipular directamente” los atributos, estos están ahí. Nota Para el ejemplo el constructor de Usuario no aporta nada nuevo, la idea aquí es que agregue posteriormente la inicialización de sus atributos particulares y luego use el constructor del Padre para inicializar los atributos heredados. Bueno, hagamos algo útil, usemos esos atributos que parecen “invisibles” ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 167. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 167 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 3 –Persona agrega su toString Definamos que Usuario es una Persona y que además de tener todos los datos de ella, se define ahora en la clase Padre el método toString Persona.php: <?php class Persona { private $_nombre; private $_apellido; public function __construct($nombre, $apellido) { $this->_nombre = $nombre; $this->_apellido = $apellido; } public function __toString() { return $this->_nombre.” “.$this->_apellido; } } Usuario.php: <?php require_once „Persona.php‟; class Usuario extends Persona { public function __construct($nombre, $apellido) { parent::__construct($nombre, $apellido); } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 168. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 168 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com index.php: <?php /* Forma de uso en index.php */ /* Solo vamos a requerir la clase que vamos a usar, no la clase padre, ese es problema de la clase Usuario (recuerden las flechas de relaciones, cada clase debe saber a quién necesita para funcionar) */ require_once „Usuario.php‟; $usuario = new Usuario(„Enrique‟,‟Place‟); echo $usuario; ¡Y funciona! ;-) La explicación es que, a diferencia que el constructor, el toString se hereda porque es público pero este se ejecuta de forma automática, sin necesidad de explicitar como en el anterior caso (constructor). Aquí es donde deberíamos entender que el principio de ocultación refuerza los diseños al ocultar y cerrar el acceso a detalles internos, pero no por eso nos impide poder aprovechar las implementaciones realizadas. Como es este caso, no tenemos acceso a los atributos de forma directa y no podemos modificarlos, pero perfectamente podemos asignarles información y usarlos. Sigamos modificando este ejemplo. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 169. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 169 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 4 – Los usuarios necesitan un id y una fecha de ingreso Imaginen lo siguiente, nuestro sistema requiere que los usuarios tengan un id y además una fecha de ingreso que será definida de forma automática desde el constructor, por lo tanto también ajustaremos la información del toString para que muestre el id de usuario. El diseño sería el siguiente: La clase Persona sigue igual, lo que cambia es la clase Usuario y se ajusta la invocación desde Index: Usuario.php: <?php require_once 'Persona.php'; class Usuario extends Persona { private $_id; private $_fechaIngreso; public function __construct($id, $nombre, $apellido) { parent::__construct($nombre, $apellido); $this->_id = $id; $this->_fechaIngreso = date('w'); } public function __toString() { return $this->_id.' '.parent::__toString(); } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 170. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 170 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com index.php: <?php require_once 'Usuario.php'; $usuario = new Usuario(1, 'Enrique','Place'); echo $usuario; // salida: “1 Enrique Place En la clase Usuario armamos el toString juntando la información de una Persona más lo que agrega de específico el Usuario. Caso 5 – Los usuarios necesitan un id único “autogenerado” Aprovecharemos la situación para explicar los “atributos estáticos” (static), o lo que podríamos traducir como “atributos / métodos de Clase”. Estos elementos son de acceso común para todas las instancias de la misma clase. Un ejemplo práctico puede ser que la clase sepa autogenerar un id nuevo (que no se repita cada vez que se construye un objeto), para ello, la clase tienen que contar el id actual para asignarle +1 al próximo usuario. El diseño sería el siguiente: La clase Persona sigue igual, lo que cambia es la clase Usuario y se agrega un atributo protegido (lo cual permitirá que una clase herede de Usuario y acceder directamente al atributo como propio) y se ajusta el constructor de la clase para no solicitar más el id. Atención: para que funcione el autogenerado de id el atributo ultimoId debe ser “estático” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 171. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 171 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Usuario.php: <?php require_once 'Persona.php'; class Usuario extends Persona { private $_id; private $_fechaIngreso; static protected $_ultimoId = 0; public function __construct($nombre, $apellido) { parent::__construct($nombre, $apellido); self::$_ultimoId += 1; $this->_id = self::$_ultimoId; $this->_fechaIngreso = date('w'); } public function __toString() { return $this->_id.'-'.parent::__toString(); } } La forma de acceder al atributo estático es usando self::$atributo SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 172. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 172 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com index.php: <?php require_once 'Usuario.php'; $usuario1 = new Usuario('Enrique','Place'); $usuario2 = new Usuario('Bruce','Lee'); $usuario3 = new Usuario('Linus','Torvalds'); echo $usuario1.‟<br>‟.$usuario2.‟<br>‟.$usuario3; Y la salida será 1-Enrique Place 2-Bruce Lee IMPORTANTE 3-Linus Torvalds Cabe destacar que esto ocurre dentro del mundo “stateless” (“estado desconectado”), por consiguiente él o los objetos se pierden luego de terminada la ejecución de la página, iniciando todo nuevamente (si restaura la pantalla volverá a contar desde “1”). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 173. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 173 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Explicación sobre la “Visibilidad Protegida” visibilidad de los atributos y Siguiendo este paralelismo, un padre puede métodos prestar el auto a su hijo de la misma forma que Existen tres posibilidades: público, privado y podría prestarlo a otro familiar, pero no a “todo protegido. el mundo” sin restricciones. “Visibilidad Pública” Un punto intermedio entre lo privado y lo público, lo “protegido” son los atributos y Se puede considerar como “sin restricciones”, lo métodos que pueden ser accedidos de forma que es público todos lo pueden acceder o directa como “propios” por parte de los “hijos” modificar. de la clase “padre”. Para las clases que no Por regla antigua de la POO, en el 99.99% de tienen una relación de parentesco su significado los casos, ningún atributo debe ser público. es igual al de privado. Para la herencia, todo lo que sea “público” se hereda a sus hijos, de igual forma que cualquiera que acceda a la clase puede ver sus atributos y métodos públicos. Recomendación “Visibilidad Privada” No hacer abuso de la visibilidad protegida, solo en casos Aquí me gusta hacer la siguiente metáfora, la excepcionales donde se justifique. En cual ayuda a clarificar mucho el funcionamiento los casos habituales todos los de esta “visibilidad” en el contexto de la atributos deben ser privados y en herencia: un atributo o método privado es casos excepcionales a través de como “la ropa interior”, es personal, es privada, algunos métodos getter/setter y nadie más tiene acceso directo a ella (me permitir de forma restringida cargar imagino que nadie presta ni usa prestada ropa un valor o consultarlo, de la misma interior, aún siendo familiares. Si es así, mis forma crear atributos y métodos disculpas por estos ejemplos, no me quise protegidos, nunca aplicar estas meter en la vida personal de nadie ;-) ). posibilidades de forma general, mecánica y sin meditar. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 174. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 174 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Caso 6 – Ejemplos varios Supongamos que nuestro Usuario genérico siguió creciendo en atributos y métodos. Ahora necesitamos definir un administrador, pero decidimos por diseño que no es “un tipo de usuario” ya que las operaciones que tiene implementadas no se ajustan a lo que estamos buscando, es un administrador que tiene la misma información que cualquier otra persona, pero se le agrega la lista de los sistemas que es responsable. El diseño sería el siguiente: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 175. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 175 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Clase abstracta Hay que tener cuidado con la traducción al En UML el diseño más robusto sería así: castellano del manual de PHP donde dice “abstracción de clases”, cuando en realidad es “clases abstractas”. Técnicamente lo que hacemos definir que la clase no puede ser instanciada, por lo que se le antepone a “class” la palabra “abstract” y en UML se representa con el nombre de la clase en cursiva ó agregando un “estereotipo” (texto que va arriba del nombre de la clase entre <<>>). Conceptualmente lo que estamos diciendo es que la clase no puede ser usada directamente y que nos servirá de molde para crear otras clases que sí serán concretas y candidatas a instanciar. Por ejemplo, imaginen que tenemos en nuestro equipo un desarrollador novato que se le En código se traduce en: encomienda hacer unas modificaciones en el sistema y en vez de usar la clase Usuario usa <?php abstract class Persona directamente la clase Persona y el sistema { empieza a fallar ya que requiere que los objetos /*sigue el código de la clase*/ sean de tipo Persona, pero las operaciones que } requiere solo están implementadas en la clase Lo cual impide hacer Usuario y la clase admin. $persona = new Persona(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 176. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 176 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Herencia Múltiple La mayoría de los lenguajes POO no implementan la herencia múltiple, no porque Aclaración les falte, se considera que lo único que aporta es más posibilidades de errores en los diseños. PHP no implementa Herencia Múltiple como la gran mayoría de los Lo que no se podría hacer es heredar de dos o lenguajes POO por considerarse más padres (siempre uno solo): inconveniente. Tampoco es un sustituto hacer uso de las interfaces (que veremos en este mismo documento) y argumentar que “se puede hacer herencia múltiple”, ya que no es lo mismo y aunque se pudiera, seguiría siendo no recomendado su uso. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 177. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 177 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Sobre-escritura” de métodos Otro elemento del lenguaje es poder sobre escribir un método que heredamos de nuestro padre. Esto se puede hacer simplemente Consejo volviendo a definir en la case “hija” un método con el mismo nombre. Nuevamente, si heredamos de una clase para luego sobre escribir el método que recibimos significará que class Padre { muy probablemente el diseño está public function metodo() mal (o que necesita ser rediseñado), { /* código */ ya que carece de sentido heredar } algo para luego modificarlo. } class Hijo extends Padre { public function metodo() { /* nuevo código */ } } Si quisiéramos usar el comportamiento original y solo modificar parte en la clase hija, deberíamos hacer lo mismo que vimos anteriormente en el constructor, invocando desde “parent”. class Hijo extends Padre { public function metodo() { parent::metodo(); /* nuevo código */ } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 178. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 178 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Evitar la herencia y la “sobre-escritura” de métodos Qué pasaría si necesitáramos endurecer el diseño y evitar que puedan indiscriminadamente modificar nuestros métodos o hasta clases a diestra y siniestra? Deberíamos usar la palabra “final”, la que impide la herencia de la clase o la sobre-escritura del método, de acuerdo en donde lo apliquemos. Impedir heredar la clase Admin final class Admin { } Impedir alterar un método que pueda ser heredado class Admin { final function metodo() { /* código */ } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 179. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 179 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Generalización” versus “Especialización” Imaginemos lo contrario, contamos con dos El término es muy usado para definir la clases que están al mismo nivel, sin relaciones “herencia”. La explicación más simple es que entre ellas, que son Usuario y Admin, ambas cada término es usado para referirse a la misma clases repiten muchos atributos y métodos herencia, pero de acuerdo a la lectura que le (como nombre y apellido), por lo que decidimos queramos dar a la relación o al análisis de hacer una “generalización” y creamos una clase diseño que estemos haciendo. Persona haciendo un factoreo de todo lo común entre ambas clases. Por ejemplo, imaginemos que solo contamos con la clase Persona y descubrimos que necesitamos una clase Usuario, podemos decir entonces que a partir de Persona hicimos una “especialización” al crear la clase Usuario, ya que tomamos un comportamiento más genérico y lo adecuamos a una clase mucho más concreta y aplicable a entornos más particulares. En resumen: podemos decir que son dos formas distintas de referirnos a la relación de “herencia”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 180. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 180 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Entonces, ¿qué es Polimorfismo? Este es el diseño En sí la palabra solo refiere a “muchas formas” y aplicado a la POO es la capacidad de poder tomar varias clases que tiene operaciones iguales y poder invocar a cualquier instancia el mismo método común. Ventajas: Poder hacer un diseño genérico que se apliquen a varios objetos que tienen operaciones comunes. Definamos el siguiente contexto: tenemos una clase Impresora que se encarga de recibir cualquier cosa y la imprime con un “echo”(a futuro podrá ser una impresora). <?php class Impresora { public function imprimir($algo) { echo $algo; } } $impresora = new Impresora(); $impresora->imprimir('Hola mundo!); Listo, tenemos nuestra clase Impresora. Ahora bien, luego de analizar este diseño decidimos que deberíamos poder recibir objetos que ellos mismos sepan cómo imprimirse, y que la impresora se encargue solo de ejecutar la acción y ella provee su “echo” (que mañana podrá ser una operación a bajo nivel que la conecte con una impresora real). Entonces, luego de discutir con nuestro equipo de desarrollo convenimos que todos los objetos que quieran imprimirse deberán tener un método “imprime” y que cada uno deberá saber qué información debe entregar a la impresora. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 181. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 181 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com La implementación Comentario index.php Este caso en particular lo llamo <?php “polimorfismo de palabra” o require_once 'Impresora.php'; require_once 'Informe.php'; “polimorfismo débil” ya que nada me require_once 'Curriculum.php'; asegura que se respeten las reglas del diseño, es más, las reglas no están Impresora::imprimir(new Informe()); Impresora::imprimir(new Curriculum() explícitas por código. ); Impresora.php Veamos a continuación cómo reforzar el diseño. <?php abstract class Impresora { public function imprimir($algo) { echo $algo->imprime(); } } Informe.php <?php class Informe { public function imprime() { return 'imprimo informe'; } } Bien, sin darnos cuenta y casi sin necesidad de entenderlo, estamos haciendo uso del polimorfismo. Nuestra clase de impresión recibe distintos tipos de objetos que comparten el mismo nombre común de un método que se requiere para que la impresora pueda funcionar. En distintas etapas de nuestro sistema veremos distintas instancias haciendo uso del mismo código de impresión: “polimorfismo”, “muchas formas”. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 182. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 182 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com “Diseño más robusto” Bien, el ejemplo anterior funciona, pero el  Aplicamos una “generalización” diseño es débil, ya que se puede decir que buscando lo común de ambas clases y entre los desarrolladores hay un “compromiso creando una clase “Hoja” que tendría de palabra” (muy probablemente no toda la información base para cualquier documentado) que toda clase que de ahora en documento que quiera imprimirse. Por más quiera imprimirse debe implementar este defecto la hoja sabe imprimirse, y en método, o de lo contrario fallará. caso de necesitar modificar el comportamiento, sobre-escribiremos el Esto es “débil” ya que no está garantizando método imprime en la clase concreta nada y dejando supeditado al desarrollador (Currículum o Informe). cumplir con lo que se requiere (que muy  Se agrega el tipo “Hoja” en el método probablemente en caso de olvidar van a tener imprimir de la clase Impresora, por que recurrir al fuente para entender cómo consiguiente no permitirá a ningún funciona la clase). objeto que no sea de tipo “Hoja” pasar por allí. Entonces, mejoremos el diseño. Bien, esto es el tradicional “polimorfismo por En este caso hicimos las siguientes herencia”. modificaciones: Ahora bien, el diseño se nos complicaría si queremos poder imprimir cosas que no necesariamente son Hojas, como un Libro, una revista, una etiqueta, etc. ¿Qué hacemos? ¿Creamos tantas impresoras como temas distintos enfrentemos? ¿La herencia está limitada? Lamentablemente aquí es donde más se queda corto el manual oficial de PHP al explicar tan brevemente qué es una interfaz (pero bueno, es un manual técnico y no una guía de programación). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 183. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 183 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Siguiendo el problema anterior, ahora tenemos varios tipos de elementos que no necesariamente son simples “hojas”. La pregunta es: ¿A nuestra impresora le debe interesar cómo son los elementos y cómo tienen que imprimirse? ¿o es un problema de cada objeto saber cómo hacerlo? Hasta ahora veníamos bien, pero si entendimos todo lo expuesto anteriormente, no podemos modificar la herencia para que un “Libro sea hijo de Hoja” (incorrecto), o que la “Impresora ahora controle libros y que todo herede de Libro” (incorrecto), o todas las variantes que se nos ocurran… el problema es que la herencia no cubre estos casos, la herencia solo se aplica cuando hay parentesco, si no lo hay, no sirve… … a menos que usemos las interfaces! SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 184. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 184 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Las interfaces: “el poder desconocido” (bueno, por los programadores PHP ;-)) Las interfaces son similares a la herencia: la herencia “agrupa” clases que “son lo mismo” (relación de parentesco) y la interface “agrupa” clases que “que realizan las mismas operaciones” (pero no necesariamente son iguales). ¿Como solucionaríamos nuestro problema? Lo que une a las clases es que todas quieren poder ser aceptadas por la Impresora y por lo tanto todas deben tener su método “imprime” El diseño de la solución sería así: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 185. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 185 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Implementación ImprimibleInterface.php Curriculum.php Impresora.php Explicación index.php Si en index.php intentamos imprimir una clase que no cumpla con la interfaz, dará error la ejecución del imprimir de Impresora, ya que solo puede aceptar objetos que implementen la interfaz Imprimible. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 186. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 186 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo funciona Detalles importantes 1. Inmediatamente que agregamos el tipo Imprimible en el método de la  La flecha es similar a herencia, solo que Impresora, cualquier objeto que quiera es “punteada” (“discontinua”), en vez pasar por ahí deberá implementar la de decir “hereda” debemos decir interface Imprimible. “realiza/implementa/cumple” con la 2. Una vez que lo implemente, el interfaz. compilador de PHP le dirá que su clase  Todos los métodos de la interfaz son no tienen el método “imprime” (esto lo “firmas”, es decir, solo va el nombre y obliga la interface, usted no la está la lista de parámetros, no existe cumpliendo), por lo tanto para que implementación, ni siquiera van las pueda ser aceptada tiene que contar llaves {}. con ese método. Sobre los diagramas: en el anterior podemos ver que la representación es similar a una clase, solo que no tiene la división donde deberían ir los atributos, solo el nombre y los métodos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 187. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 187 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Repaso de lo visto hasta el momento Detalles a tener en cuenta: en este diagrama se ve la interface como si fuera una clase sin la zona de atributos (por que no tiene) y para reforzar la documentación (no haría falta igual, se sobre entiende) le agrego un comentario como estereotipo “interface”. Dependiendo de la herramienta, el libro, el autor, el docente, la interfaz se puede representar también como un círculo, lo cual en lo personal prefiero (si la herramienta me deja o encuentro como) ya que a simple vista se detectan fácilmente todas las interfaces. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 188. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 188 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Las interfaces son “contratos de implementación” Una interface es conceptualmente lo que se dice un “contrato de implementación”, ya que para usar un servicio (Impresora) tiene que cumplir un contrato (interfaz) que lo obliga a cumplir una serie de requisitos (las firmas de métodos que aparecen en la interfaz). De esta forma obtenemos un diseño robusto, ya que nada queda supeditado a la palabra y no depende del conocimiento o desconocimiento del código, ya que al solo hacer un “implements” el mismo compilador nos va guiando con los métodos que nos faltan cumplir Anexo Se recomienda leer:  Herencia de clases y el "Principio de Liskov" (actualizado 15/10/2007)  "Herencia múltiple en PHP5" SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 189. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 189 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Hicimos la primer introducción a la Herencia y las Interfaces, las diferencias entre ambas, y cómo se aplica el polimorfismo y los distintos tipos que hay. También destacamos que conceptualmente el Polimorfismo es un “patrón estratégico” y que las interfaces son “contratos de implementación”. ¿Dudas? ¡envíame tu consulta! ;-) Necesitas más ejemplos para entender este capítulo? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 190. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 190 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 16 - Ejercicio “Clase de Persistencia” Ya que estamos en un capítulo bastante avanzado en los conceptos, en esta oportunidad te voy a soltar un poco más de la mano para que puedas probarte hasta donde puedes llegar (trata de hacer el ejercicio sin mirar la solución) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 191. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 191 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos Se necesita diseñar e implementar una clase de persistencia genérica llamada BaseDeDatos que pueda recibir distintos tipos de "Manejadores de Base de Datos" como ser MySQL, Postgres, etc, desde su constructor. Para ello deberán hacer uso de las interfaces, creando una que se llame ManejadorBaseDeDatosInterface y que tenga en su "contrato de implementación" las operaciones más básicas y elementales: conectar, desconectar, traer datos ejecutando una consulta SQL, etc. Posteriormente y para dividir responsabilidades, necesito que creen una clase SQL que se encargue de procesar todos los pedidos SQL en partes, así poder a futuro hacer mayores controles. Por ejemplo, debería tener métodos como:  addCampo  addTabla  addWhere  addOrder  etc Esta primera versión debe contemplar las operaciones de un SELECT y las condiciones serán por defecto "AND". Con esta clase lo que haremos es evitar que la clase de persistencia tenga el trabajo de hacer estos controles y se lo derivaremos a una clase especializada para esa tarea. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 192. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 192 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo deberá ser el contenido de la clase Index en index.php: require_once 'BaseDeDatos.php'; require_once 'MySQL.php'; require_once 'Sql.php'; $bd = new BaseDeDatos(new MySQL()); $sql = new Sql(); $sql->addTable("usuarios"); $sql->addWhere("id = 1"); $sql->addWhere("id = 1"); $sql->addWhere("nombre = 'enrique' "); $usuario = $bd->ejecutar($sql); // esto genera SELECT * FROM usuarios WHERE id = 1 AND nombre = 'enrique'; El resultado es un array asociativo que se obtiene de la consulta a la base de datos. Deberán realizar el UML y el código de toda la implementación de Index funcionando (no más código que este) y convertido en una clase (el código anterior en un método "run"). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 193. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 193 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución El objetivo de este ejercicio fue obligar a enfrentar una situación muy cotidiana, como puede ser las clases de “persistencia de datos” (estas preguntas se repiten una y otra vez en los foros). Definición Con “Persistencia” nos referimos tanto a guardar como recuperar datos de un medio de almacenamiento permanente, por defecto hablamos de una base de datos, pero perfectamente podría ser un archivo de texto plano u otro medio. Hay un frase que dice: "Cualquier problema en computación puede resolverse añadiendo otra capa de abstracción" La forma de separar el problema de tener distintos motores de base de datos es, justamente, agregando una nueva capa de abstracción y evitar conocer directamente los detalles concretos de una base de datos en particular. Veamos la evolución, paso a paso… SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 194. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 194 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Primer escenario: “crear una Tercer escenario: “abstraer conexión a la base de datos” el tipo de base de datos” Lo primero que implementamos si necesitamos Imaginen que nuestro producto crece y lo persistir nuestros datos en una base de datos empezamos a comercializar para muchas son las funciones de conexión de un motor de plataformas, y que uno de nuestros nuevos base de datos como MySQL. Entonces, requerimientos es poder contemplar varios buscamos cada una de las sentencias en el motores de bases de datos. Para ello tenemos manual y en el peor de los casos nuestro código que “contener el foco de cambio”(*) y adaptar se plaga de sentencias tan específicas como: a nuestro sistema para que solo agregando mysql_connect, mysql_query, etc. “código nuevo sin modificar lo existente” pueda así soportar más motores de bases como Lo que podría suceder luego es que si Oracle, MSSQL Server, Informix, Sybase, quisiéramos cambiar de motor de base de Firebird, etc, etc. datos, tendríamos que modificar todas las sentencias de nuestro sistema, con el costo que Por lo tanto, lo que aplicaremos a continuación esto tiene. es un principio de diseño que se llama “Abierto / Cerrado” y utiliza el polimorfismo a través de Segundo escenario: “crear herencia o de interfaces. una clase de persistencia” Tratando de prever esta situación podríamos crear una “nueva capa de abstracción” y generar un clase genéricas (conectar, traer Definición datos, desconectar) que nos permita (*)Foco de cambio: se le dice al lugar “esconder” el código específico de MySQL. En o lugares de nuestro sistema que por caso de necesitar alguna funcionalidad extra o los requerimientos que estamos cambiar de motor, simplemente el impacto en desarrollando, es seguro que ahí nuestro sistema estaría reducido a modificar habrán cambios (agregar, modificar, nuestras funcionalidades de una clase que etc) por consiguiente debemos oculta los detalles de implementación. preverlo de alguna forma para bajar De todas formas, aún seguiríamos dependiendo su costo de modificación / de tener una implementación para una u otra mantenimiento. base de forma exclusiva. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 195. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 195 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diseño UML SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 196. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 196 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Ejemplo codificado index.php <?php require_once 'BaseDeDatos.php'; require_once 'MySQL.php'; require_once 'Sql.php'; abstract class Index { public function run() { $bd = new BaseDeDatos(new MySQL()); $sql = new Sql(); $sql->addTable('usuarios'); $sql->addWhere('id = 1'); $sql->addWhere('id = 1'); $sql->addWhere("nombre = 'enrique' "); $usuario = $bd->ejecutar($sql); echo highlight_string(var_export($usuario, true)); } } Index::run(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 197. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 197 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ManejadorBaseDeDatosInterface.php <?php interface ManejadorBaseDeDatosInterface { public function conectar(); public function desconectar(); public function traerDatos(Sql $sql); } BaseDeDatos.php <?php require_once 'ManejadorBaseDeDatosInterface.php'; require_once 'Sql.php'; class BaseDeDatos { private $_manejador; public function __construct(ManejadorBaseDeDatosInterface $manejador) { $this->_manejador = $manejador; } public function ejecutar(Sql $sql) { $this->_manejador->conectar(); $datos = $this->_manejador->traerDatos($sql); $this->_manejador->desconectar(); return $datos; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 198. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 198 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com MySQL.php <?php require_once 'ManejadorBaseDeDatosInterface.php'; class MySQL implements ManejadorBaseDeDatosInterface { const USUARIO = 'root'; const CLAVE = ''; const BASE = 'tarea5'; const SERVIDOR = 'localhost'; private $_conexion; public function conectar() { $this->_conexion = mysql_connect( self::SERVIDOR, self::USUARIO, self::CLAVE ); mysql_select_db( self::BASE, $this->_conexion ); } public function desconectar() { mysql_close($this->_conexion); } public function traerDatos(Sql $sql) { $resultado = mysql_query($sql, $this->_conexion); while ($fila = mysql_fetch_array($resultado, MYSQL_ASSOC)){ $todo[] = $fila; } return $todo; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 199. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 199 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Sql.php <?php class Sql { private $_colWhere = array(); private $_colSelect = array('*'); private $_colFrom = array(); public function addTable($table) { $this->_colFrom[] = $table; } public function addWhere($where) { $this->_colWhere[] = $where; } private function _generar() { $select = implode(',',array_unique($this->_colSelect)); $from = implode(',',array_unique($this->_colFrom)); $where = implode(' AND ',array_unique($this->_colWhere)); return 'SELECT '.$select.' FROM '.$from.' WHERE '.$where; } public function __toString() { return $this->_generar(); } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 200. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 200 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Principio de diseño “Abierto Imaginar que las clases MySQL y Postgres están / Cerrado” “colgadas” desde sus flechas en un punto de apoyo como es la Interface, para agregar una nueva funcionalidad simplemente debemos Enunciado formal: agregar nuevas clases “colgadas de la interfaz” –por ejemplo- creando una nueva clase para el "Entidades de Software (clases, módulos, nuevo motor de base de datos, implementamos funciones, etc) deberían ser abiertas para la la interfaz y esta nos obligará a crear todos los extensión y cerradas para la modificación" métodos necesarios para que la clase genérica BaseDeDatos nos acepte y ejecute. Lo cual significa que nuestro costo en el desarrollo se da cuando diseñamos un sistema que cuando hay cambios de requerimientos debemos modificar constantemente, por lo Comentario tanto un buen diseño deberá ser “Abierto / Cerrado”, se diseñará una vez y cuando se Se dice que todo buen diseño (como necesite agregar nueva funcionalidad se hará las implementaciones de los sin modificar el código existente, solo Patrones de Diseño) de alguna forma agregando código nuevo. u otra termina cumpliendo con este principio. ¿Donde está el principio aplicado? En la siguientes “flechas”: Pasando en limpio: cada vez que necesitemos soportar otro motor de base de datos crearemos una nueva clase, requerimos la interfaz (“contrato de implementación”) y esta nos obligará a implementar los métodos requeridos para que todo funcione de acuerdo al diseño. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 201. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 201 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen En mundos más “arquitectónicos” como es Java, donde no es nada raro aplicar patrones de diseño, el uso de las interfaces es algo habitual y necesario. Cuando diseñan una solución, generalmente crean una clase que ofrece un “servicio” y a su vez una “interfaz” que deberán cumplir todas las clases que quieran utilizar ese servicio, aplicando de esta forma el principio de diseño “Abierto/Cerrado”. Recuerda: trata de mecanizar esta buena práctica, una clase que ofrece un servicio debe implementar en conjunto una interfaz que servirá de guía para todas las clases que quieran usar ese servicio. Repítelo como un monje budista. Tienes una pequeña duda? No hay dudas pequeñas… Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 202. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 202 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 17 - Ejercicio “Librería y la búsqueda de Libros” Con el objetivo de reafirmar un tema tan importante como las interfaces, se solicita implementar y resolver un nuevo problema: la búsqueda de libros por distintos filtros que no conocemos en su totalidad y que irán aumentando con el tiempo. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 203. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 203 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos “Tengo una librería y estoy implementando un sistema para registrar libros. Actualmente mi principal problema es la búsqueda de los libros, ya que sé que luego de implementado mi sistema de búsquedas me pedirán agregar nuevos filtros de información (he detectado el "foco de cambio"), por lo tanto deberé contemplar en el diseño este problema.” El diseño borrador es el siguiente: Tener muy en cuenta las relaciones El diseño debe poder soportar las siguientes presentadas en los diagramas: búsquedas:  Index no ve directamente a los libros  Todos los libros de un año: 2008  Index no ve directamente a los  Todos los libros del autor llamado Autores "Enrique Place"  Todos los libros del tema "PHP"  Todos los libros que tengan en su título la palabra "Java" (deberán buscar la coincidencia parcial). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 204. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 204 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución El objetivo de este ejercicio es completar el entendimiento de cómo funcionan las interfaces, cómo se aplica el principio de diseño “Abierto / Cerrado” y cómo se pueden implementar las relaciones en situaciones donde el acoplamiento es alto entre las clases de la solución. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 205. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 205 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diseño “Borrador” (con partes incompletas) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 206. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 206 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diseño “Final” cumpliendo con todos los requerimientos Agregados  Se agrega la firma del método en la interfaz CriterioFiltro  Los nombres de las clases Filtro y sus atributos  Se obvian todos los get, set, constructores y toString del diagrama ya que se considera que el lector objetivo es un desarrollador que sabe determinar cuándo necesitarlos implementar (para este diagrama no aportan detalles relevantes).  Se agrega en Libro un método getAutores para poder obtener luego su lista de autores. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 207. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 207 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com index.php: <?php require_once 'Libreria.php'; require_once 'FiltroAnual.php'; require_once 'FiltroAutor.php'; require_once 'FiltroTema.php'; require_once 'FiltroTitulo.php'; abstract class Index { public function run() { $libreria = new Libreria(); /* * Carga de libros */ $libreria->addLibro('Introduccion a Java','Java',2007); $libreria->addLibro('Introduccion a PHP','PHP',2008); $libreria->addLibro('Introduccion a los Patrones de Diseño','Patrones',2007); $libreria->addLibro('Introduccion a Zend Framework','Zend',2008); /* * Carga de autores */ $libreria->addAutorLibro('Introduccion a PHP', 'Enrique', 'Place'); /* * Búsqueda de libros */ $libros2008 = $libreria->busqueda(new FiltroAnual(2008)); $librosAutor = $libreria->busqueda(new FiltroAutor('Enrique','Place')); $librosTema = $libreria->busqueda(new FiltroTema('PHP')); $librosTitulo = $libreria->busqueda(new FiltroTitulo('Java')); echo self::_librosEncontrados2Html("Libros del 2008: ",$libros2008); echo self::_librosEncontrados2Html("Libros del Autor: ",$librosAutor); echo self::_librosEncontrados2Html("Libros del Tema: ",$librosTema); echo self::_librosEncontrados2Html("Libros del Titulo: ",$librosTitulo); } private function _librosEncontrados2Html($titulo, $array) { return $titulo.': ' . implode(', ', $array).'<br><br>'; } } Index::run(); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 208. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 208 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Comentarios sobre el diseño  Se requieren exactamente las clases que dice el diseño UML, ni más ni menos.  Se cargan libros y autores sin acceder desde Index a las clases Libro y Autor, todo a través de la clase Librería.  Este diseño permite tener un solo diseño de búsqueda y poder intercambiar fácilmente los algoritmos de los criterios de búsqueda.  El principio Abierto / Cerrado nos dice que un buen diseño es “cerrado al cambio y abierto a la extensión”, en este caso el “foco de cambio” será agregar nuevos criterios de búsqueda, tema que está resuelto “agregando solo código nuevo” (sin modificar código existente) permite incorporar nueva funcionalidad (esto no es menor si entendemos que tocar algo que funciona puede generar a su vez nuevos bugs o nuevos cambios en cadena). Aquí logramos bajar el costo de mantenimiento de esta parte del sistema. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 209. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 209 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Libreria.php: <?php require_once 'Libro.php'; require_once 'CriterioFiltro.php'; class Libreria { private $_colLibros = array(); public function busqueda(CriterioFiltro $filtro) { $librosRetorno = array(); foreach( $this->_colLibros as $libro){ if( $filtro->esSeleccionable($libro)){ $librosRetorno[]= $libro; } } return $librosRetorno; } public function addLibro($titulo, $tema, $año) { $this->_colLibros[] = new Libro($titulo,$tema,$año); } public function addAutorLibro($titulo, $nombreAutor, $apellidoAutor) { foreach($this->_colLibros as $libro){ if($libro->getTitulo() == $titulo){ $libro->addAutor($nombreAutor,$apellidoAutor); } } } } Comentarios  La clase Librería sólo requiere Libro, no requiere directamente la clase Autor  La búsqueda se realiza recibiendo un criterio y este criterio va recibiendo cada uno de los ítems de la colección de libros, cada vez que el libro coincida con el criterio de filtro este método retornará “true”, por lo tanto lo guardaré en un array para luego devolver a todos los objetos Libros encontrados. El filtro sólo tiene una responsabilidad, confirmar si se cumple el criterio o no.  Para agregar un autor de un libro se hace una búsqueda y posteriormente se le da todos los datos al libro para que guarde su autor, todo sin tener que crear una instancia a este nivel. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 210. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 210 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Libro.php: <?php require 'Autor.php'; class Libro { private $_titulo; private $_tema; private $_año; private $_colAutores = array(); public function __construct($titulo,$tema,$año) { $this->_titulo = $titulo; $this->_tema = $tema; $this->_año = $año; } public function addAutor($nombre,$apellido) { $this->_colAutores[] = new Autor($nombre,$apellido); } public function getTitulo() { return $this->_titulo; } public function getTema() { return $this->_tema; } public function getAño() { return $this->_año; } public function getAutores() { return $this->_colAutores; } public function __toString() { return $this->_titulo; } } Comentarios  El Libro sólo conoce al Autor  En el UML se obvian todos los get y toString por considerarlos triviales a la hora de abordar el problema real. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 211. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 211 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Autor.php: <?php class Autor { private $_nombre; private $_apellido; public function __construct($nombre, $apellido) { $this->_nombre = $nombre; $this->_apellido = $apellido; } public function getNombre() { return $this->_nombre; } public function getApellido() { return $this->_apellido; } public function __toString() { return $this->_nombre . ' ' . $this->_apellido; } } Comentarios  Esta clase no aporta nada nuevo SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 212. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 212 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com CriterioFiltro.php: <?php interface CriterioFiltro { public function esSeleccionable(Libro $libro); } Comentarios  No aporta nada nuevo de lo visto a la fecha. FiltroAutor.php: <?php require_once 'CriterioFiltro.php'; class FiltroAutor implements CriterioFiltro { private $_nombre; private $_apellido; public function __construct($nombre,$apellido) { $this->_nombre = $nombre; $this->_apellido = $apellido; } public function esSeleccionable(Libro $libro) { $encontrado = false; foreach($libro->getAutores() as $autor){ if($autor->getNombre() == $this->_nombre && $autor->getApellido() == $this->_apellido){ $encontrado = true; } } return $encontrado; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 213. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 213 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Comentarios  A este nivel sólo conozco a la interfaz  esSeleccionable recorre una lista de los autores de un libro para ver si al final coincide con lo solicitado.  Cambia la forma de requerir las clases (sujeto a discusión y definición de criterios): podríamos decir que el filtro depende del libro para poder trabajar y no estaría mal implementarlo, pero para este diseño se toma como criterio que las clases de filtro están “altamente acopladas” a los componentes de la clase Librería y por lo tanto no van a trabajar sin ella: sin depender de nada más, sólo de los componentes asociados a la Librería, sin relación directa con Libro (usará el require_once de Libro existente desde Librería).  Se crea una “dependencia indirecta” entre el filtro de autor y el autor propiamente dicho: se vuelve a repetir el caso donde el objeto (libro) expone sus componentes internos. El filtro sólo depende del Libro pero este es requerido en la Librería, y a través del require_once de Autor en Libro se accede al mismo. La pregunta que siempre debemos hacer es: ¿qué forma es más conveniente? ¿permitir exponer componentes internos de una clase a favor de simplificar su uso? ó ¿esconder todos los detalles internos para no violar el “Principio de Ocultación” y que los elementos externos no dependan de los elementos internos de las clases con las cuales se relacionan? (efectos en cadena). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 214. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 214 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Cuando vi por primera vez en la universidad materias como Diseño Orientado a Objetos y Patrones de Diseño (todo bajo Java), este fue particularmente uno de los ejercicios que más “abrió mi mente” y me hizo terminar de descubrir lo importante que son los diseños, las relaciones, los diagramas y fundamentalmente, que gran herramienta son las interfaces. No es raro ver en Java que para hacer o usar tal o cual funcionalidad de una clase hay que implementar primero una interfaz para llegar hasta la clase que ofrece la funcionalidad que necesitamos. Al principio no será natural esta forma de trabajo ya que poco estamos acostumbrados en el mundo PHP a hacerlo de esta forma, pero con el tiempo y la práctica tenemos que mecanizarnos que cada vez que necesitemos implementar un servicio deberemos hacer en conjunto una interfaz que guíe cómo se debe usar y qué requisitos se deben cumplir. Repite como un monje budista: “Un servicio (clase) debe disponer de una interfaz que obligue a cumplir con un contrato de implementación”. Alguna parte quedó confusa? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 215. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 215 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 18 - “Los Paquetes en UML” Los paquetes son la representación de un agrupador de clases (o de otros paquetes) en un sistema Orientado a Objetos, lo que generalmente se traduce físicamente en un directorio (aunque dependiendo de la tecnología esto puede ser más “lógico” que “físico”). Esto nos permitirá organizar nuestro sistema y tener un nivel mayor de abstracción SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 216. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 216 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cómo se representan En UML se hace gráficamente con el dibujo La clase Index se encuentra en la raíz de de una "carpeta" como representación del nuestro proyecto, y la relación siempre con concepto de "agrupador de clases". Este y entre los paquetes es de "dependencia". gráfico se traduce simplemente en un Aquí tenemos un nuevo nivel de abstracción subdirectorio físico en nuestra aplicación, y donde "conocemos" que nuestra clase en el caso particular de PHP, cuando una Index depende de un paquete "Lógica" (que clase de un paquete deba apuntar a una a dentro contendrá clases) y que a su vez el clase en otro paquete, tendremos una paquete de Lógica depende del paquete de referencia con un require_once con la ruta "Dispositivos". directorio/Clase.php. Depender de un paquete no significa otra cosa que "depender concretamente de una Según este diagrama: clase del interior del paquete" pero para la representación, nosotros dependemos del "paquete que la contiene". Por ejemplo, es como decir que "el mecánico trabaja sobre el motor (paquete)" y no tener que dar la lista de todos los componentes del motor, o tener que decir que está trabajando concretamente sobre alguna parte en particular del motor (en este contexto no nos interesa tener tanto detalle, estamos abstrayendo complejidad para que sea más fácil de manejar nuestro sistema). Podríamos diseñar un sistema que tenga los paquetes de Ventas, Stock y Contabilidad donde cada uno tendrá una lista extensa de clases pero que en algún momento nos interesará manejarlo a un nivel mucho más abstracto como el "paquete". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 217. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 217 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Qué es una Arquitectura de 3 capas? No es más que crear 3 paquetes con nombres como: presentación, dominio y persistencia, y darle a cada uno una responsabilidad concreta. La regla será que siempre deberán entrar las peticiones desde la interfaz (lo que usa el usuario), pasar por el dominio (donde realmente se resuelve el sistema) y finalmente la capa de persistencia (donde se guardan o recuperan los datos). Cada capa recibe una petición de la otra, si alguna no tiene nada que hacer con ella, simplemente juega de "pasamanos" para la capa correspondiente según su responsabilidad. El diagrama tradicional para una arquitectura de 3 capas: Nota: veremos luego cómo se aplica en el último ejercició práctico de este libro. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 218. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 218 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Que son entonces los Namespaces? PHP5.3 incorporará, a pesar de haber seguido Por muchos años los desarrolladores que siempre a Java, por primera vez el concepto conocemos de otros lenguajes notamos en PHP de "namespaces". Será la primera versión y aún la ausencia del soporte por parte del lenguaje al no está claro la forma de usarlo (a la fecha manejo de "paquetes" a nivel conceptual siguen habiendo discusiones sobre "lo mal qu (inicialmente lo diagramamos en UML pero en ese está implementando" esta funcionalidad). algún momento debemos codificarlo). Por lo pronto es como si no contáramos con ella y debiéramos esperar hasta PHP6. Tanto Java como .Net permiten codificar claramente un "Paquete UML": Para más información sobre este interesante tema, se recomienda leer  Java tiene la sentencia "import" que permite definir el paquete en el cual  PHP5: Diseño en 3 capas y problemas con pertenece la clase en cuestión y a su vez incluir él o los paquetes que subdirectorios necesitamos acceder desde una clase  "Petición para soporte de Name Spaces en particular.  En .Net, por ejemplo con Visual Basic, PHP5" el nombre cambia a "namespace" y a pesar que sirve para implementar los  http://ar2.php.net/manual/es/language.na "paquetes", es un concepto un poco mespaces.php más amplio : permite definir que una clase es parte de un paquete, independientemente de donde se encuentre físicamente el archivo de la clase, por lo que podríamos tener varios archivos distribuidos en un sistema pero ser parte del mismo "paquete". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 219. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 219 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Los paquetes permiten un nuevo nivel de abstracción y que podemos usar para definir una arquitectura dividida en 3 capas, que no es más complejo que separar físicamente los archivos de las clases bajo el criterio único de la responsabildad de la capa. También vimos que esto puede cambiar con un concepto un poco más amplio como son los Namespaces, pero que a los efectos ambos sirven para representar los "paquetes". Al final de cuentas es un mecanismo más que sirve para estructurar nuestro sistema en elementos de más alto nivel y luego relacionarlos entre ellos. Este capítulo te pareció muy breve? Solicita ampliarlo Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 220. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 220 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 19 - Ejercicio “Programación ‘Orientada a la Implementación’ vs ‘Orientada a la Interface’" Penúltimo ejercicio y terminamos cerrando con un concepto que considero fundamental, además del tema de las interfaces, entender la diferencia entre la programación "orientada a la implementación" versus programación "orientada a la interface". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 221. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 221 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Abril de 2006 escribí un artículo que cubre el 50 % del tema donde explico lo que es la programación orientada a la interfaz y dejo la promesa de terminarlo algún día. Ese día llegó y lo haremos juntos cómo la penúltimo ejercicio de este libro. Tomando el artículo de referencia (actualizado al día de hoy): Programación: "Orientada a la Implementación" versus "Orientada a la Interface" - Parte 1 Index usa la clase MaquinaDeEscribir.php que se encuentra dentro del paquete"logica", por consiguiente, desde la vista de paquetes, Index depende del paquete "logica", y como dentro de lógica la clase MaquinaDeEscribir depende de dos clases que están dentro del paquete "dispositivos", el paquete "logica" (donde está MaquinaDeEscribir), depende del paquete "dispositivos". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 222. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 222 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos Enunciado:"La máquina de escribir tiene un dispositivo de entrada de datos (teclado) y un dispositivo de salida de datos (impresora)" Como convención los nombres de paquetes son siempre en minúsculas y se traducen como un subdirectorio en nuestro sistema como forma de organizar nuestras clases. Veamos entonces qué hay dentro de cada paquete. Para este caso se agrega como "estereotipo" de cada clase el nombre del paquete al cual pertenecen: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 223. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 223 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Lo que solicita el ejercicio es: 1. Dos implementaciones que deberán llamarse version1 y version2 2. La primera tendrá la programación "orientada a la implementación", deberán completar el diagrama presentado y hacer su implementación. 3. La segunda deberá ser programación "orientada a la interfaz" (como dice su nombre, usando "interfaces"), también deberán hacer el diagrama e implementación de la solución (todo de acuerdo a los conceptos vertidos en el artículo presentado oportunamente en el blog): 4. Deberá depender de las interfaces y no de las clases concretas. 5. Finalmente, cuando el diseño esté completamente terminado, ver la forma de solucionar un problema en el diseño: cambiar la dependencia entre los paquetes, ya que la lógica no debería depender de los detalles de implementación de los dispositivos, sino, los dispositivos cambiar en caso de que la lógica cambie ("lo menos importante depende de lo más importante"). Dudas, como siempre, envíala! Sugerencia Se recomienda la lectura profunda y meditada del artículo de referencia. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 224. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 224 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución El objetivo de este ejercicio estaba dividido en dos partes: La primera parte, repasar el concepto y la forma de requerir las clases y cómo hacerlo en caso de tener subdirectorios (representados en UML como “paquetes” para agrupar clases). La segunda parte, buscaba seguir aplicando con ejemplos por qué cada vez que implementamos un “servicio” debemos de forma casi mecánica incluir una interfaz para dejar el camino definido a cualquier clase que necesite usar ese servicio. Una vez concluidos estos dos ejercicios, en esta misma corrección, explicaré algunos conceptos sobre “Análisis & Diseño Orientado a Objetos” que creo (aunque escapa el alcance del temario de este libro) es el momento ideal para abordar. No desaprovechemos la oportunidad ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 225. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 225 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Parte 1: hacer una “máquina de escribir” siguiendo el ejemplo del artículo Se creará una clase “MaquinaDeEscribir” que estará en el paquete “lógica” (donde se define la forma en que trabajará el sistema). Posteriormente esta “lógica” hará uso de los dispositivos de más bajo nivel para poder acceder a la entrada y salida de datos. El diseño UML era el siguiente: Y la vista de paquetes era la siguiente SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 226. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 226 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Implementación index.php MaquinaDeEscribir.php (dentro del paquete “lógica”) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 227. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 227 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Teclado.php (dentro del paquete “dispositivos”) Impresora.php (dentro del paquete “dispositivos”) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 228. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 228 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Conclusión Según se explica en el artículo de referencia (PHPSenior), la lectura de los diagramas y sus relaciones nos hacen llegar a la siguiente conclusión: “La lógica de nuestro sistema depende de los dispositivos, por lo pronto esto significa un problema en nuestro diseño , ya que según el sentido de las flechas, cualquier cambio en nuestros dispositivos de bajo nivel afectarán el corazón de nuestro sistema” Esto es tan peligroso como decir que habría que cambiar la implementación del sistema de gestión de nuestra empresa cada vez que cambie la forma de entrada o salida de datos, algo que es ridículo. Sería correcto si cambia la lógica central de nuestro sistema se vean afectados los dispositivos de bajo nivel y estos deban ser adaptados, pero no al revés! Esto lo podremos revertir usando interfaces, por lo tanto veremos todo el proceso de mejorar nuestro diseño a continuación… SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 229. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 229 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Parte 2: Agregar interfaces al diseño propuesto en la parte 1 Aquí separamos la clase MaquinaDeEscribir de depender directamente de las clases Teclado e Impresora. Hay varios detalles importantes:  Pasamos de depender de “implementaciones concretas” a depender de “implementaciones abstractas”, ya que para MaquinaDeEscribir lo único con que se relaciona es con elementos de tipo las interfaces y no se preocupa cómo se implementen las clases que cumplan con el “contrato de implementación” (es problema de la interfaz definir lo que se necesita y de la clase que quiere el servicio en cumplir los requisitos necesarios para usarlo).  Casi sin darnos cuenta estamos cumpliendo con el principio “Abierto/Cerrado”, ya que vamos a estar “cerrados al cambio pero abiertos a la extensión”, el “foco de cambio” será agregar nuevos dispositivos pero no necesitaremos modificar el funcionamiento de MaquinaDeEscribir, ya que su algoritmo será siempre el mismo. Aún hay otro detalle más, no está representada la clase Index, la que nos da el contexto de cómo se ejecuta todo este diseño… SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 230. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 230 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Se podría decir que solo falta la flecha de Index a la clase MaquinaDeEscribir: Pero no, no es suficiente, ya que para que MaquinaDeEscribir pueda funcionar depende de que le ingresen dos elementos de tipo Lector y Escritor. Prestar atención, la clase MaquinaDeEscribir no depende directamente de las clases concretas, sí las terminará usando a través de polimorfismo (a esto se le llama “indirección” o “relación indirecta”: usa elementos concretos pero depende en realidad de elementos abstractos). El diagrama correcto debería ser el siguiente: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 231. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 231 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Implementación Lo medular de la implementación es el nuevo método “run” de la clase MaquinaDeEscribir, que recibe ahora dos tipos de objetos, “lectores” y “escritores”: index.php MaquinaDeEscribir.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 232. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 232 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com LectorInterface.php EscritorInterface.php Impresora.php Nota: como Impresora y la interfaz Escritor son del mismo paquete, no llevan rutas en el require_once que hagan referencia desde donde se ejecuta Index, ya que esta ubicación puede cambiar y la relación entre los paquetes debe estar fija por diseño (revisar las flechas del diagrama anterior). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 233. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 233 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Teclado.php Nota: el require_once es igual que en el caso anterior, se asume la invocación desde el paquete. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 234. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 234 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¿Y el Diagrama de Paquetes? … ¿cómo quedará ahora la relación vista a nivel de paquetes? Viendo el sentido de las flechas y solo representando una flecha de dependencia (así son siempre entre paquetes) resumiendo todas las existentes (aumentamos el nivel de abstracción) … Paquete “lógica” Paquete “dispositivos” Entonces, la vista de paquetes se ve así: Lo que no debe asustar es que existan dos flechas de dependencia contra el paquete desde Index, ya que esto es normal (para usar un servicio o conjunto de clases podremos depender de uno o más paquetes), lo que sí debería preocuparnos (además de evitar las relaciones cíclicas) es que –a pesar de haber mejorado hacia un diseño “que depende de interfaces y no de implementaciones concretas”- nuestro paquete de “lógica” sigue dependiendo del paquete de “dispositivos”… SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 235. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 235 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com El “Principio de Inversión de dependencias (DIP)” ¿Cómo solucionamos esto? Cambio de sentido de flechas entre paquetes Hay una técnica para cambiar el sentido de las dependencias entre paquetes que es mover las clases de un paquete hacia el otro paquete, o en su defecto, creando un tercer paquete y mover las clases para cambiar el sentido de las direcciones. Para este caso concreto, moveremos las interfaces a la clase que provee el servicio, por lo tanto cambiaremos el sentido de las dependencias entre paquetes: Paquete “lógica” Paquete “dispositivos” Nuevamente, prestar atención el sentido de las flechas de implementación, ahora apunta a las clases que están en el paquete de arriba (“lógica”), así que pasando en limpio el diagrama de paquetes ahora quedaría: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 236. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 236 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Alternativa: como solución alternativa podríamos crear un tercer paquete para las Interfaces, donde la lógica y los dispositivos dependerían, rompiendo la relación directa que antes existía. ¡Ey! ¡Finalmente logramos nuestro objetivo!, ahora el sistema está mejor diseñado, implementado “Orientado a la Interfaz”, cumple con el principio de diseño “Abierto/Cerrado” y el paquete de más “alto nivel” no depende de los detalles o cambios del paquete de más “bajo nivel”!! SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 237. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 237 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Premisa: “En general, las interfaces pertenecen a las entidades que las emplean” El paquete de “lógica” conoce y tiene una interfaz para conectarse con el paquete “dispositivos”, pero no sabe qué hay dentro del paquete “dispositivos”. Para más información: DIP - Dependency Inversion Principle (Principio de Inversión de Dependencias) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 238. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 238 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Comentarios adicionales Pienso que era difícil intuir el desenlace de esta árbol”, estudiar el impacto de los paquetes, los nueva historia de suspenso ;-) patrones y los principios de diseño, y esa “magia de druidas” se llama “Análisis y Diseño A esta altura del libro espero haber logrado Orientado a Objetos”. transmitir un poco de experiencia y dejarles una “semilla” para seguir investigando y Nos estamos encontrando en el próximo profundizando el tema de la “Programación desafío, el último ejercicio del libro, donde Orientada a Objetos” y que no es solo “crear aplicaremos el último de los conceptos que clases y hacer objetos”. quiero dejarles: “la arquitectura de tres capas” Existe otra disciplina que estudia cómo poder aplicar los conceptos más allá de la “visión del Necesitas el código completo de la solución del ejercicio? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 239. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 239 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 20 - Ejercicio “Desarrollar un sistema de ABM de usuarios” Este fue el último ejercicio de los cursos a distancia que integraban todos los conceptos vertidos en los capítulos de este libro. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 240. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 240 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Requerimientos "Ustedes están a prueba por la empresa SURFORCE y a modo de probar sus conocimientos para obtener el puesto de PHP Senior recibirán un sub-sistema que deberán concluir con todo éxito. Lo que hay desarrollado hasta el momento es el esqueleto de un sistema en 3 capas que cumple con el siguiente UML: Como se puede observar, todo parte de un único archivo inicial "index.php" y posteriormente accede a la capa de presentación, luego a la capa de dominio y finalmente a la capa de persistencia. Se entiende que no se pueden saltear las capas propuestas ni el sentido de las dependencias entre paquetes. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 241. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 241 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Lo que se deberá desarrollar en primera instancia es un sistema de ABM de Usuarios (Altas/Bajas/Modificaciones) con un diseño de interfaz similar a entornos como Ruby On Rails (a continuación un ejemplo de cómo se deberá ver la interfaz): La primer pantalla es un listado de los registros existentes en la tabla, posteriormente en cada línea existen las opciones de mostrar toda la información, editarla o eliminarla. Al final del listado se puede observar la opción de dar de alta un usuario. Podrán bajar un sistema base de ejemplo (sin terminar) y ustedes deberán: 1. Aplicar todos los conocimientos vistos hasta el momento (Kiss es fundamental). 2. Relevar todo lo existente en el sistema entregado (archivo de configuración, entender cómo funciona, cual es la forma de trabajo, qué falta, etc). 3. Implementar todo lo necesario para cumplir el ejemplo de diseño anterior, logrando hacer un listado de usuarios, detalle, alta, baja y modificación de datos. 4. Presentar el diagrama UML final con todos los agregados realizados. Se sugiere la lectura complementaria de los siguientes materiales:  PHP5: Diseño en 3 capas y problemas con subdirectorios  Conceptos: "Separar el código de la capa de presentación"  "Petición para soporte de Name Spaces en PHP5" SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 242. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 242 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Se entregará un archivo comprimido con el código fuente del sistema con todas las capas y hasta una carpeta llamada "sql" que contendrá una base de datos y una tabla usuarios para poder iniciar su desarrollo. ¡Ese puesto en la compañía puede ser tuyo!" Nota: El diseño general de 3 capas del sistema base que les entrego fue usado en un sistema real de aplicaciones SMS para celulares (no es meramente "otro problema teórico para resolver" ). Para bajar el archivo comprimido con el código fuente Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 243. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 243 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Solución La idea de esta tarea es presentar un problema completo a partir de un template de un sistema existente, el cual deberían usar de apoyo para cumplir con los requerimientos solicitados. A pesar que el ejercicio permite aplicar algunos conceptos aprendidos en este libro, no deja de ser un ejercicio y como tal, desborda de programación “artesanal”. Hay muchos detalles que no son tenidos en cuenta, como puede ser la seguridad del sistema o cómo procesar más eficientemente la capa de presentación en conjunto al armado de html, estilos, etc. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 244. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 244 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Cambios que se aplicaron en la resolución A grandes rasgos se hicieron las siguientes modificaciones General  Se usó el criterio de definir estático todo lo que era genérico o general de la clase, y lo opuesto para referirse a los métodos que se aplican a una instancia de un objeto. Es decir, si la clase usuario se usaba para traer todos los usuarios del sistema, debía ser Usuario::getAll(), y los métodos estándar se aplicaban a una instancia única que representaba a “él” usuario.  Se creó un método load de la clase dominio/Usuario para una vez obtenido el id de usuario por parámetro, este cargue el usuario que se encuentre en la persistencia. Se puede decir que hace el efecto de una “fábrica” (patrón de diseño). Persistencia  Modificamos la persistencia para que retorne los datos en un array  Modificamos la clase Sql para contemplas los demás casos del ABM Dominio  Agregamos el constructor para inicializar los datos que consideramos básicos del objeto  Modificamos el getAll para que pueda retornar una colección de objetos array  Creo el toString para que cada usuario sepa cómo imprimirse cuando lo use la capa de presentación Presentación  Se armaron todos los formularios requeridos para el ABM  Se agregaron redirecciones para luego de procesar regrese a la página inicial. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 245. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 245 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagrama tradicional de paquetes SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 246. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 246 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagramas de clases y sus paquetes de origen SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 247. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 247 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Diagramas de Secuencia Se sabe que los diagramas de clases son una “foto estática” del diseño general de una solución, pero no siempre es suficiente para entender cómo un diseño de clases debe trabajar, qué se invoca primero y qué después, para ello existen los “diagramas de secuencia” que nos permiten tener una visión más dinámica y temporal de cómo interactúan los objetos una vez que se inicia una acción determinada. Caso: Ver detalle de un usuario (ejemplo) Aquí se pude observar cómo se van sucediendo las invocaciones de los métodos, y cómo es que una clase se relaciona con otra invocando los métodos de la clase siguiente. La línea temporal se define de arriba – abajo, el primer método que se invoca es el que hace Index al ejecutar UsuarioPresentacion::detalle() y sigue bajando hasta llegar a la última ejecución. Por ejemplo, 1. Index invoca el detalle() de UsuarioPresentación, 2. posteriormente este invoca el método load() de la clase Usuario y 3. finalmente este invoca el load de la clase UsuarioPersistencia (todo un “pasamanos”). Aunque generalmente no se representa, al final de la cadena lo que sucede es que la última invocación retorna información, que recibe la clase siguiente al invocación, hasta llegar otra vez a la clase inicial (secuencia inversa): 1. UsuarioPersistencia retorna datos, 2. Usuario lo recibe y arma los objetos para luego retornarlos a 3. la clase UsuarioPresentación para luego esta retornar a 4. Index, recibe lo que tiene que mostrar (html) y así ejecuta un “echo” SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 248. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 248 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Toda documentación UML debería contar con los correspondientes diagramas de secuencia que documenten cómo se usan las clases entre ellas y en qué momento una invoca métodos de la otra. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 249. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 249 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Partes esenciales del código de la solución Index.php <?php require_once 'configuracion.php'; require_once PRE . DIRECTORY_SEPARATOR . 'UsuarioPresentacion.php'; abstract class Index { const SIN_PARAMETROS = 0; static public function run($get) { DEBUG ? var_dump($get) : null; if(count($get) != self::SIN_PARAMETROS){ self::_procesarModulo(); }else{ self::_porDefecto(); } } static private function _porDefecto() { echo 'Pagina por Defecto'; echo '<ul>'; echo '<li><a href="?modulo=listado">listado</li>'; echo '</ul>'; } static private function _moduloNoExiste() { echo 'Modulo no Existe'; } Nota Para facilitar el entendimiento del código el método a continuación se pasa entero a la siguiente página (todo es parte de la misma clase) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 250. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 250 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com static private function _procesarModulo() { switch ($_GET['modulo']){ case 'listado': if (isset($_GET['mensage']) && $_GET['mensaje'] != "") { echo "El Usuario ha sido ".$_GET['mensaje']." correctamente"; } echo UsuarioPresentacion::listadoUsuarios(); break; case 'detalle': echo UsuarioPresentacion::detalle($_GET['id']); break; case 'nuevousuario': echo UsuarioPresentacion::mostrarFormNuevoUsuario(); break; case 'insertar': if(UsuarioPresentacion::guardarUsuario( $_POST['nombre'], $_POST['apellido'])) { header("Location:index.php?modulo=listado&mensaje=guardado"); } break; case 'modificarusuario': echo UsuarioPresentacion::mostrarFormModificarUsuario($_GET['id']); break; case 'modificar': if(UsuarioPresentacion::modificarUsuario( $_POST['id'], $_POST['nombre'], $_POST['apellido'])){ header("Location:index.php?modulo=listado&mensaje=modificado"); } break; case 'eliminar': if(UsuarioPresentacion::eliminarUsuario($_GET['id'])) { header("Location:index.php?modulo=listado&mensaje=eliminado"); } break; default: self::_moduloNoExiste(); break; } } } Index::run($_GET); SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 251. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 251 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com UsuarioPresentacion.php <?php require_once 'configuracion.php'; require_once DOM . DIRECTORY_SEPARATOR . 'Usuario.php'; abstract class UsuarioPresentacion { static public function listadoUsuarios() { $usuarios_arr = Usuario::getAll(); $retorno = '<ul>'; foreach($usuarios_arr as $objetoUsuario){ $retorno .= '<li>'.$objetoUsuario; $retorno .= " <a href='?modulo=detalle&id=".$objetoUsuario- >getId() ."'>Mostrar</a> | "; $retorno .= " <a href='?modulo=modificarusuario&id=". $objetoUsuario- >getId() ."'>Modificar</a> | "; $retorno .= " <a href='?modulo=eliminar&id=". $objetoUsuario- >getId() ."'>Eliminar</a> | "; $retorno .='</li>'; } $retorno .= "<li><a href='?modulo=nuevousuario'>Nuevo Usuario</a>"; $retorno .= '</ul>'; return $retorno; } static public function detalle($id) { return Usuario::load($id); } static public function mostrarFormNuevoUsuario() { return self::_mostrarFormulario(); } static public function mostrarFormModificarUsuario($id) { $usuario = Usuario::load($id); $form = self::_mostrarFormulario( $id, $usuario->getNombre(), $usuario->getApellido(), "modificar" ); return $form; } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 252. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 252 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com static public function modificarUsuario($id, $nombre, $apellido) { $usuario = new Usuario($id, $nombre, $apellido); return $usuario->modificarUsuario(); } static public function eliminarUsuario($id) { $usuario = new Usuario($id); return $usuario->eliminarUsuario(); } static private function _mostrarFormulario($id = "", $nombre = "", $apellido = "", $accion = "insertar") { $retorno = ""; $retorno = "<form action='?modulo=".$accion."' method='post'>"; $retorno .= "<input type='hidden' name='id' value='".$id."' />"; $retorno .= "Nombre:<input type='text' name='nombre' value='". $nombre."' /> " ; $retorno .= "Apellido:<input type='text' name='apellido' value='".$apellido."' />"; $retorno .= "<input type='submit' name='submit' value='".ucwords($accion)."' / >"; $retorno .= "</form>"; return $retorno; } static public function guardarUsuario($nombre, $apellido) { $usuarioNuevo = new Usuario(NULL,$nombre, $apellido); return $usuarioNuevo->guardarUsuario(); } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 253. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 253 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Usuario.php <?php require_once 'configuracion.php'; require_once PER . DIRECTORY_SEPARATOR . 'UsuarioPersistencia.php'; /** * Description of Usuario * * @author Pc */ class Usuario { private $_id; private $_nombre; private $_apellido; public function __construct($id = "", $nombre = "", $apellido = "") { $this->_id = $id; $this->_nombre = $nombre; $this->_apellido = $apellido; } public function getId() { return $this->_id; } public function getNombre() { return $this->_nombre; } public function getApellido() { return $this->_apellido; } public static function getAll() { $usuarioPersistencia = new UsuarioPersistencia(); $datos_array = $usuarioPersistencia->getAll(); foreach($datos_array as $usuario_array){ $id = $usuario_array['id']; $nombre = $usuario_array['nombre']; $apellido = $usuario_array['apellido']; $retorno[] = new Usuario($id, $nombre, $apellido); } return $retorno; } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 254. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 254 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com public static function load($id) { $usuarioPersistencia = new UsuarioPersistencia(); $datos_array = $usuarioPersistencia->load($id); foreach($datos_array as $usuario_array){ $usuario = new Usuario( $id, $usuario_array['nombre'], $usuario_array['apellido'] ); } return $usuario; } public function guardarUsuario() { $usuarioPersistencia = new UsuarioPersistencia(); $guardo = $usuarioPersistencia->guardarUsuario( $this->_nombre, $this->_apellido ); return $guardo; } public function modificarUsuario() { $usuarioPersistencia = new UsuarioPersistencia(); $modificar = $usuarioPersistencia->modificarUsuario( $this->_id, $this->_nombre, $this->_apellido ); return $modificar; } public function eliminarUsuario() { $usuarioPersistencia = new UsuarioPersistencia(); $eliminar = $usuarioPersistencia->eliminarUsuario($this->_id); return $eliminar; } public function __toString() { return $this->_id." ".$this->_nombre." ".$this->_apellido; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 255. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 255 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com UsuarioPersistencia.php <?php require_once 'configuracion.php'; require_once PER . DIRECTORY_SEPARATOR . 'BaseDeDatos.php'; require_once PER . DIRECTORY_SEPARATOR . 'MySQL.php'; require_once PER . DIRECTORY_SEPARATOR . 'Sql.php'; class UsuarioPersistencia { public function getAll() { $bd = new BaseDeDatos(new MySQL()); $sql = new Sql(); $sql->addTable('usuarios'); return $bd->ejecutar($sql); } public static function load($id) { $bd = new BaseDeDatos(new MySQL()); $sql = new Sql(); $sql->addTable('usuarios'); $sql->addWhere("id = ".$id); return $bd->ejecutar($sql); } public function guardarUsuario($nombre, $apellido) { $bd = new BaseDeDatos(new MySQL()); $sql = new Sql(); $sql->addFuncion("insert"); $sql->addTable("usuarios"); $sql->addSelect("nombre"); $sql->addSelect("apellido"); $sql->addValue($nombre); $sql->addValue($apellido); return $bd->ejecutar($sql); } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 256. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 256 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com public function modificarUsuario($id, $nombre, $apellido) { $bd = new BaseDeDatos (new MySQL()); $sql = new SQL(); $sql->addFuncion("update"); $sql->addTable("usuarios"); $sql->addSelect("nombre='".$nombre."'"); $sql->addSelect("apellido='".$apellido."'"); $sql->addWhere("id=".$id); return $bd->ejecutar($sql); } public function eliminarUsuario($id) { $bd = new BaseDeDatos (new MySQL()); $sql = new SQL(); $sql->addFuncion("delete"); $sql->addTable("usuarios"); $sql->addWhere("id=".$id); return $bd->ejecutar($sql); } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 257. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 257 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Resumen Quiero felicitarte si llegaste hasta el final del libro y completaste todos los ejercicios. Honestamente, el gusto de escribir todo este material fue mío y espero que sigamos en contacto a través del sistema para usuarios, cursos a distancia, libros o simplemente un comentario en el blog consultando alguna duda :-) Baja el ejercicio completo con todo el código comentado Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 258. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 258 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 21 - Anexo: “Manejo de excepciones” Un tema no menos importante en la POO es el manejo de errores, algo que todos los lenguajes modernos soportan y dan la posibilidad de unificar la forma de manejarlos en el sistema. Esta funcionalidad se agregar a partir de PHP5. Manual oficial: http://www.php.net/manual/es/language.exceptions.php SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 259. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 259 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Introducción Una excepción es una situación anormal que En la programación tradicional, haríamos algo ocurre durante la ejecución de un sistema que como esto (extrato del manual oficial): no está contemplada en el flujo esperado de nuestro código. <?php $link = mysql_connect( Por ejemplo, una parte de nuestro sistema tiene 'localhost', la responsabilidad de listar los usuarios 'mysql_user', actualmente existentes. Esa es la funcionalidad 'mysql_password' ); esperada y así lo implementamos. Necesariamente a bajo nivel vamos a requerir if (!$link) { die( operaciones de persistencia, es decir, 'Could not connect: ' conectarnos a la base de datos, requerir los . mysql_error() datos y desconectarnos. Ese es el flujo normal y ); } se espera que todo salga bien. echo 'Connected successfully'; Lamentablemente debemos contemplar todas mysql_close($link); las situaciones que “no son esperadas / no son ?> normales” para que nuestro sistema sepa cómo proceder en caso de fallas:  el servidor de base de datos está fuera Aquí solo estamos controlando que se pudo de servicio, hacer la conexión a la base de datos, pero no los  cambió la clave del usuario que usamos demás casos. para conectarnos,  no existe la tabla de usuarios,  algún campo de la tabla cambió de nombre,  etc. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 260. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 260 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Podríamos agregarle entonces: <?php $link = mysql_connect( 'localhost', 'mysql_user', 'mysql_password' ); if (!$link) { die( 'Could not connect: ' . mysql_error() ); } echo 'Connected successfully'; $result = mysql_query("SELECT id,email FROM people WHERE id = '42'"); if (!$result) { echo 'Could not run query: ' . mysql_error(); exit; } $row = mysql_fetch_row($result); echo $row[0]; // 42 echo $row[1]; // the email value mysql_close($link); ?> Si somos observadores nos iremos dando cuenta que el código para validar todas las situaciones anómales empieza a crecer y superar en extensión al verdadero código funcional, donde muy probablemente entraremos a anidar “if/else/elseif” y/o “switchs”, y así seguirá creciendo en complejidad y aumentando la posibilidad de fallos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 261. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 261 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Básicamente cómo funcionan En esta situación no logramos mucho más las excepciones avance, ya que al fallar alguna rutina dentro del “try” simplemente pasa el controlo al “catch” y Existen dos claras zonas, la primera de “try” que toda la información queda dentro de la se traduce cómo “intentar ejecutar el código instancia “$e” de tipo clase Exception. que está entre llaves y que es posible que pueda fallar” y el “catch”, el código previsto para tratar el fallo que pueda ocurrir. try{ /* Aquí va el código que podría fallar*/ }catch(Exception $e){ /* Si alguna línea dentro del try falló, podremos tomar el control aquí */ } Si quisiéramos emular una situación donde si falla simplemente envíe un mensaje en pantalla, podríamos hacer lo siguiente: try{ Aclaración /* Aquí va el código Si vienes prestando atención, el echo que podría fallar */ $e retorna información porque la clase Exception implementa el }catch(Exception $e){ método toString() con el mensaje echo $e; básico de error. } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 262. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 262 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Estructura interna de una clase Exception La estructura de una clase Exception es (según el manual oficial): class Exception { protected $message = 'Unknown exception'; // exception message protected $code = 0; // user defined exception code protected $file; // source filename of exception protected $line; // source line of exception function __construct($message = null, $code = 0); final function getMessage(); // message of exception final function getCode(); // code of exception final function getFile(); // source filename final function getLine(); // source line final function getTrace(); // an array of the backtrace() final function getTraceAsString(); // formated string of trace /* Overrideable */ function __toString(); // formated string for display } Esto significa que podemos hacer uso de los métodos listados para poder, si así lo deseamos, generar un mensaje a medida para el usuario de acuerdo a nuestras necesidades. Si hacemos un echo $e; obtendremos el mensaje estándar de la Excepción, que generalmente podría ser bastante extenso e informativo, tal vez ideal para ambientes de desarrollo pero no tanto para producción, ya que nuestra seguridad se podría compromenter al darle tantos detalles a un “extraño”. Un ejemplo de un mensaje más breve y sin menos datos: try{ /* Aquí va el código que podría fallar*/ }catch(Exception $e){ echo "Ocurrió un error inesperado, " ."por favor consultar a soporte técnico"; } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 263. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 263 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Tal ver preferimos dar una referencia, un código para poder completar en un formulario de asistencia técnica. try{ /* Aquí va el código que podría fallar*/ }catch(Exception $e){ echo "Ocurrió un error inesperado, " ."por favor consultar a soporte técnico " " (Código de Error ".$e->getCode().")"; } Pero tal vez no queremos que el usuario sepa tanto, somos un poco más proactivos y preferimos dejarles un mensaje genérico y que se genere un registro en el log, o si es muy grave, nos envíe una notificación por email o hasta un SMS a nuestro celular. try{ /* Aquí va el código que podría fallar*/ }catch(Exception $e){ echo "Ocurrió un error inesperado, " ."ya se envió una notificación al departamento de sistemas " " En un momento se estarán contactando con usted"; Mail::send("sistemas@surforce.com", "Error:".$e ); } Esto es lo básico de cómo responder a un error, pero casi de la misma forma que podríamos hacerlo con un if/else. Ahora veremos las diferencias. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 264. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 264 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Importante: PHP no tiene Por lo tanto tenemos dos problemas: excepciones por defecto  En PHP5 debemos crearnos nuestras Una de las ventajas viene directamente por el propias excepciones a partir de la única paradigma POO, como las excepciones se clase que nos provee el lenguaje: representan con objetos, podemos extender la Exception. clase Exception y crear nuestras propias  Todo lo que atrapemos debemos excepciones de acuerdo a nuestras necesidades. asegurarnos que retorne una Excepción, y como el lenguaje no lo En lenguajes como Java ya existen por defecto cientos de clases agrupadas por temas como hace por defecto, debemos hacerlo a base de datos, manejo de archivos, para nivel de clases propias, validando problemas matemáticos, arrays, etc. Y lo más internamente de la forma tradicional importante, todo retorna por defecto una (if/else/switch), pero al subir de nivel el resto podrá hacer uso normal de los excepción, algo que no sucede en try/catch. PHP5! Sí, lamentablemente aún estamos en pañales ¿Cuan grave es no tener Excepciones con las excepciones,pero se espera que por lo menos en PHP7 se modifiquen todas las rutinas predefinidas y por defecto? del lenguaje para que así lo hagan. Que es muy normal que lo primero que probemos sea una sentencia de conexión a una base de datos (como vimos al principio de este Zend Framework tiene Excepciones capítulo) y que las excepciones no funcionen, Predefinidas y por Defecto dejandonos algo confusos. Una de las ventajas de este framework es que todos sus componentes tiene manejo de excepciones, es decir, incorpora desde Zend_Exception (algo más completo que Exception estándar de PHP) y muchas más clases para cada situación, muy similar a Java. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 265. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 265 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Ejemplo funcional de excepciones en PHP5 Aquí veremos cómo hacerlas funcionar sin excepciones por defecto creando una clase genérica que tendrá todo el código del primer ejemplo donde retornaba los mensajes de error clásicos y los cambiaremos ahora por excepciones (comentaré las líneas que cambian y agrego a continuación las nuevas): <?php class BaseDeDatosEjemplo { private $_link; public function __construct() { $this->_link = mysql_connect( 'localhost', 'mysql_user', 'mysql_password' ); if (!$link) { // die('Could not connect: ' . mysql_error()); throw new Exception('Could not connect: ' . mysql_error()); } } public function traerDatos() { $result = mysql_query("SELECT id,email FROM people WHERE id = '42'"); if (!$result) { //echo 'Could not run query: ' . mysql_error(); throw new Exception('Could not run query: ' . mysql_error()); //exit; } $row = mysql_fetch_row($result); mysql_close($link); return $row; } } Se podría decir que el "throw" es similar a "return algo", lo que hace es "lanzar la excepción" a un nivel más arriba, donde se invocó originalmente la rutina, para que tomen el control de la situación anómala y procedan en consecuencia. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 266. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 266 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Por lo tanto, si todo el código anterior Importante: el orden de las queremos “atraparlo” en un "try" para tenerlo excepciones controlado en caso de fallas, deberíamos hacer hay que tener en cuenta el orden de las lo siguiente: excepciones dentro del catch, ya que debe ir primero la excepción más específica e ir try{ bajando a la excepción más genérica. Si $bd = new BaseDeDatosEjemplo(); colocamos la excepción genérica primero, todos $datos = $bd->traerDatos(); los fallos entrarán ahí y no a la excepción }catch(Exception $e){ acorde al tipo de error. echo "Falla al recuperar " ."los datos"; } Esta es la forma de trabajo más elemental, posteriormente habría que crear distintos tipos de Excepciones de acuerdo al tipo de falla, como por ejemplo: try{ /* Aquí va el código que podría fallar*/ }catch(DbException $e){ /* Aquí va el código para responder a un error de Base de Datos */ }catch(Exception $e){ /* Aquí va el código para responder a un error Genérico */ } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 267. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 267 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Beneficios de las Excepciones  Permiten separar el código de manejo de errores del código que debe cumplir con los requerimientos de funcionalidad de la aplicación  Permite un manejo homogéneo de los errores: evitará que tengamos distintas estructuras para contener los errores, como ser: en algunos casos una cascada de if, en otros un switch y tal vez en otros algún objetos de manejo de errores.  No solo transfiere el control del sistema de un lugar a otro, sino que también trasmite información sobre la situación anómala: como unidad todas las excepciones manejan objetos de tipo Excepción y como todo objeto, tendrá atributos y métodos relacionados con el manejo de errores. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 268. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 268 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En Resumen Las excepciones son herramientas que cuentan todos los lenguajes POO modernos y no se discute su utilidad. Es fundamental entender los conceptos base, qué es una Excepción, que no todo debería considerarse como tal y solo las "situaciones anómalas / no esperadas" de nuestro sistema. Como desarrolladores siempre tendremos dos caminos para decidir: si ocurre una excepción, es responsabilidad de esa parte del código resolverla o deberá "relanzarla" al nivel superior para que este se encargue de hacer algo al respecto. Es muy habitual que si tenemos un sistema de 3 capas y falla en la capa de persistencia, esta relance la excepción al dominio y este a la capa de presentación para que se transforme en una ventana de error que será entregada elegantemente al usuario como: "Ha ocurrido un error al intentar guardar los datos, por favor pruebe nuevamente dentro de unos minutos" ;-) Quieres saber si hay alguna actualización de este capítulo? Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 269. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 269 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Capítulo 22 - Cierre del libro y reflexiones finales ¿No pasa que en algunas películas, cuando parece que todo terminó, al final se muestra una secuencia que nos adelanta el inicio de una continuación? ¿la revelación de una nueva trama? Bien, aquí viene ;-) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 270. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 270 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Aquí hay algo que está mal.. ¿no se dieron cuenta? Si dijimos durante casi la mitad del taller que lo más importante es el “dominio” y que las flechas evidencian que si hay una relación de A -> B significa que todo cambio de B afecta a A, qué pasa con este modelo tradicional de “3 capas”? Index -> presentación -> dominio -> persistencia Mmmm… todo bien que presentación dependa de dominio que es lo más importante, si este cambia, es lógico que cambie las pantallas… pero está bien que dominio dependa de la persistencia?! eh?! ah?! ¿Entonces, todo lo que aprendimos está mal? ¿equivocado? ¿erróneo? ¡AGHHHH! SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 271. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 271 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com …No del todo! ;-) Lo que significa que el diseño tradicional de “3 capas” con el mismo sentido de flechas desde la ”presentación” pasando por “dominio” y terminando en “persistencia”, por más aceptado que esté, el diseño no cumple con todos los conceptos que vimos, por lo tanto, el verdadero diseño de 3 capas bien implementado debería ser como en el diagrama de la derecha (“persistencia apuntando a dominio”). Es verdaderamente interesante el mundo más allá de la Programación Orientada a Objetos y que entra en lo que es el Análisis y Diseño Orientado a Objetos, un nivel más, el arte de los druidas, el camino del “Arquitecto de la Matrix”, poder detectar la estabilidad de los paquetes, los principios que afectan a todos los diseños, cómo mejorar nuestro diseño o detectar sus fallas, que… vendrá en un futuro no muy lejano! Ahora sí, hasta el próximo libro, curso, taller o post en el blog! ;-) FIN. Confirma que estás leyendo la última versión de este libro Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 272. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 272 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Enrique Place http://phpsenior.blogspot.com http://enriqueplace.blogspot.com http://www.surforce.com ¿Qué te pareció el libro? ¡Envíame tus comentarios! Ingresa a http://usuarios.surforce.com SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 273. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 273 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Anexo I: "Qué es lo nuevo en PHP5?" Este anexo está basado en el artículo What's new in PHP5 (18/3/2004) publicado por Zend Developer Zone, al cual le agrego un poco más de información y comentarios extras sobre mi opinión de cada uno de ellos. Veamos un resumen de "lo nuevo" en PHP5. "La mejor manera de estar preparados para el futuro es inventarlo" (John Sculley) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 274. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 274 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Características del Lenguaje PHP5 es la versión que hace un salto importante con respecto a la POO, incorporando funcionalidades que cualquier lenguaje OO necesita como mínimo (algo que PHP4 carecía completamente). Así que la mayoría de lo que veremos a continuación no son más que "una puesta al día" de PHP con respecto a los demás lenguajes POO (antes no se le podía decir que lo era por carecer de todo lo que veremos). 1.Modificadores de acceso "public/private/protected" Se incorpora el uso de modificadores de acceso "public / private / protected" para atributos y métodos. Definir el "alcance o visibilidad" (scope) es importante para poder aplicar el "principio de ocultación", es decir, proteger al objeto del exterior y solo permitir acceso a los datos y comportamientos que nosotros especifiquemos. PHP4 carecía completamente de esta posibilidad y antes "todo era público". Aunque por defecto cualquier método que no diga nada al principio de su firma signifca que es "public", para unificar el criterio y claridad de la codificación se sugiere que todos los método públicos inicien siempre con el "modificador de acceso" correspondiente. ¡Dile "no" a los atributos públicos! Aunque "tecnicamente lo permita", esto no significa que se deban usar "atributos públicos". Recuerda, por defecto en POO se considera que todos los atributos deben ser "no públicos" y solo en algunos casos muy especiales (0.001 %) se justificaría su uso, pero serían contextos muy "raros" (tal vez en el desarrollo de un generador de código o un framework, pero no en un sistema desarrollado típicamente en POO). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 275. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 275 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 2. El método reservado __construct() En PHP4 para definir un constructor había que escribir un método con el mismo nombre de la clase (al igual que lo hace Java) PHP5 incorpora ahora un método exclusivo, a través del métod reservado __construct 3. El método reservado __destructor() De la misma forma que el constructor, se agrega un método reservado que permite agregar funcionalidad cuando el objeto se destruya (por ejemplo, desconectarnos de una base de datos en el momento que se haga un unset de la instancia). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 276. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 276 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 4. Interfaces Se incorpora por primera vez la posibilidad de crear interfaces y poder agrupar clases "que hacen lo mismo" o "que tienen operaciones comunes". A diferencia de la herencia, se pueden implementar varias interfaces, por lo que podemos llegar a tener una clase que herede de una clase y que además implemente varias interfaces: SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 277. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 277 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 5. El operador "instance of" Se deja de usar el operador de PHP4 is_a() y se agrega uno nuevo más especializado para objetos: "es instancia de": if ($obj instance of Circle) { print '$obj is a Circle'; } Aquí estamos preguntando si la instancia "obj" es de tipo "la clase Círculo". ¡No uses el "instanceof"! Aunque "tecnicamente exista y pueda usarse ", no se recomienda estar preguntando a las instancias cual es su clase, ya que rompemos los diseños genéricos que pueden hacer uso del polimorfismo (estrategia base del DOO). Cuando trabajemos con varios objetos debemos manipularlos "genéricamente" y cada objeto debe saber cómo comportarse. Si por cada objeto vamos a preguntar de que tipo es y en base a eso hacer algo, estamos atando el comportamiento de nuestro código y tendremos una cadena de if's/switchs para contemplar cada caso (tenemos un nuevo "foco de cambio", ya que necesitaremos seguir preguntando por cada nuevo tipo que se cree). 6. Operador "final" para los métodos Final es otra herramienta que nos permite reforzar el diseño de nuestra clase. En este caso podemos definir qué métodos que otra clase vaya a heredar no pueden ser modificados a través de la "sobreescritura" de los mismos (los métodos deben usarse tal cual se reciben de su padre). En este ejemplo podemos decir que diseñamos un método (por lo simple y concreto) que no debería existir ninguna situación donde necesite que sea modificado, por lo tanto "lo aseguramos" para que nadie que herede nuestra clase pueda modificar su comportamiento (ya que sería muy raro). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 278. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 278 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 7. Operador "final" para la clase Este operador también se aplica a las clases, impidiendo que una clase se pueda heredar, por lo que estamos entonces obligando a usar la clase sin posibilidad de crear otra en base a la original. final class FinalClass { } class BogusClass extends FinalClass { } En este caso el sistema dará un error grave porque se intentó heredar de una clase que está definida como "final". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 279. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 279 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 8. Método reservado __clone para clonado de objetos Desde que PHP5 empieza a trabajar por referencia y no por valor (como hacía por defecto PHP4), toda asignación con objetos representa una copia de la referencia a un mismo objeto, pero nunca se crea otro objeto duplicado. Si necesitáramos hacerlo (en casos muy especiales), podremos usar el comando clone. Pero, tal vez queramos especificar cómo debería clonarse el objeto, por lo que podemos definir en el comportamiento interno del mismo a través del método reservado __clone() todas las operaciones que necesitemos. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 280. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 280 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com En este ejemplo podemos ver cómo se usa el método __clone, en el cual agregaremos que si alguien quiere clonar nuestro objeto no tenga el valor de la clave del objeto original. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 281. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 281 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 9. Atributos Constantes para las clases Ahora se incorpora la posibilidad de incluir atributos constantes en las clases. Hay que tener en cuenta que como toda constante, estas son siempre públicas, y no podemos desde la clase esconderlas (su ámbito siempre será la clase). En este ejemplo podemos observar el uso de las constantes como forma de documentar y evitar los "números mágicos" (técnica de Refactoring), donde para conocer la lista de parámetros (sin importar saber de memoria sus valores) se lo podemos pedir a la misma clase consultando sus constantes (que son públicas y su propia descripción auto-documentan su uso). Esta práctica es ampliamente usada en muchos lenguajes como Java (tanto para clases como para interfaces) y se recomienda adoptar siempre que definamos parámetros o valores en nuestro sistema. Nota: las constantes se consideran "elementos de clase" (ver más adelante el apartado sobre "métodos estáticos"), por lo tanto dentro de la clase deberías usar self::CONSTANTE (igual puedes usar Clase::CONSTANTE). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 282. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 282 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 10. Miembros estáticos o de clase (static) Las clases pueden incluir elementos "estáticos" (también denominados "elementos de clase"), accesibles a través de la clase y no de la instancia. El ejemplo más común es crear una clase Usuario que cada vez que se cree una instancia, la clase sepa cual es el último número de id y asignar dinámicamente un número más para el nuevo usuario. El atributo debería ser "de clase / estático", ya que su valor, en oposición a los atributos, son compartidos por todas las instancias de la misma clase. En este ejemplo podemos ver cómo a través del "atributo de clase" se mantiene la información entre instancias de la misma clase. Hay que tener en cuenta que este ejemplo no es del todo útil más allá de explicar cómo funciona, ya que cada vez que reiniciemos nuestra página, el contador empezará nuevamente de cero (para evitarlo habría que persistir esta información de alguna forma). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 283. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 283 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com Otro uso común de los miembros estáticos es en el patrón Singleton, el cual está pensado para retornar siempre la misma instancia de un objeto: class Singleton { static private $_instance = NULL; private function __construct() {} static public function getInstance() { if (self::$_instance == NULL) { self::$_instance = new Singleton(); } return self::$_instance; } } SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 284. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 284 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 11. Métodos estáticos o de clase (static) De la misma forma que ahora se pueden crear atributos de clase, también se pueden crear métodos de clase o estáticos. En esencia la lógica es la misma, son métodos que se comparten entre elementos de la misma clase y no son "de instancia" (no requieren una instancia para poder usarse). Un uso que se le da a los miembros de clase es crear una serie de métodos que no necesariamente están afectados a una instancia y que bien se pueden usar como una "librería" (conjunto de funcionalidades agrupadas bajo una clase), como sucede con clases bases en Java. Una clase String en Java tendrá todo un conjunto de métodos que no necesariamente se aplican solo a una instancia, y que pueden invocarse llamando a la clase y al método correspondiente. Imaginemos que queremos que PHP imite el comportamiento de Java, por lo tanto necesitaríamos crear clases base como Integer, String, Date, etc (que actualmente no existen), por lo que deberíamos buscar en el manual de PHP todas las funciones aisladas entre sí que tratan un mismo tema y agruparlos bajo la misma clase (espero que en algún futuro no muy lejano suceda en PHP). Así, con todas estas funcionalidades deberíamos poder aplicarlas tanto en una instancia o a través de una clase, para tener la libertad de no necesitar crear una instancia cada vez que queramos usar una funcionalidad que está aislada del contexto de la instancia. Por ejemplo, PHP tiene una función strtolower(), si quisiéramos ordenarlo en un entorno 100% Orientado a Objetos, podríamos decir que debería ser un método de una clase String, y deberíamos poder usarlo en cualquier ambiente, tanto bajo una instancia como sin ella. Si creamos un método común, solo lo podremos usar con una instancia: Bien podríamos cambiar el diseño y decir que no necesitamos crear constantemente una instancia que luego no se va a usar, por lo tanto cambiemos el método a "de clase". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 285. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 285 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com De ahora en más podremos usarla de dos formas. Hay que tener en cuenta que si llamamos al método internamente, debemos cambiar el $this que se aplica a instancias por el método self que se aplica a elementos de clase. Otro ejemplo de uso muy tradicional es la típica clase Index, donde no necesariamente requiere que creemos una instancia, ya que solo la usaremos para iniciar la ejecución de un sistema, por lo que acceder a un método es suficiente. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 286. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 286 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 12. Clases Abstractas "abstract" es una forma de decir que una clase "no se puede instanciar". Por ejemplo, si tenemos una clase que es demasiado "genérica" para realmente necesitar que se instancie, la aseguramos colocando un "abstract", por lo tanto solo servirá como "modelo" para poder hacer "herencia". Ej, la clase Persona, en la vida real es muy poco probable que necesitemos instanciarla, pero si contamos con clases de tipo Usuario que heredan características de Persona, sí les servirá de modelo. El otro caso, es la clase Index, que no se ejecuta como una instancia, lo hace como una clase, por lo tanto para hacer más robusto el diseño le agregamos "abstract" para que nadie la use de otra forma. abstract class MyBaseClass 13. Métodos abstractos Un método abstracto obliga a una clase que hereda de la clase que lo contiene (al método abstracto) a definir el contenido de ese método. Una clase que tiene métodos abstractos debe definirse como clase abstracta. De la misma forma que podemos decir que una clase abstracta puede ser usada como una clase "modelo" para que otra herede de ella, podemos decir que un método abstracto sirve de modelo para que una clase que herede tenga que implementar el método definido en la clase padre. abstract class MyBaseClass { abstract function display(); } ¿clases abstractas == interfaces? Si hemos prestado atención, con las clases y métodos abstractos podemos "simular" el comportamiento de las interfaces, al crear un "contrato de implementación". Pero no son lo mismo, recordar que la herencia agrupa "elementos del mismo tipo / relación de parentesco" y las interfaces "elementos que hacen lo mismo sin importar si tienen o no relación de parentesco" SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 287. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 287 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 14. Validación de Tipo a través de Clases ( type hints) PHP desde sus orígenes es un lenguaje "dinámicamente tipado", lo que hace que cada variable defina su tipo según el valor que se le asigne, pero en sí no necesitamos como Java que es obligatorio definir el tipo antes de usarlo. Con el tiempo nos dimos cuenta que "tanta libertad" (no manejar tipos) puede no ser tan buena idea, por lo que ahora en más se habilita para los objetos la posibilidad de verificar "el tipo" del parámetro que estamos recibiendo, permitiendo con esto hacer diseños más robustos donde "no todo es tan dinámico", ya que ahora podemos aplicar un poco más de control. Si no se cumple con el tipo especificado, dará un error. function expectsMyClass(MyClass $obj) { } Un detalle importante a tener en cuenta es que la validación es "mecánica", es decir, cuando recibe el objeto pregunta cual es su tipo (con qué clase se creó o cuales son sus padres) y luego comparará exactamente con la cadena de texto que agregamos a la izquierda (en este caso MyClass). De aquí se desprenden dos cosas: 1. No es técnicamente necesario incluir la clase de filtro, por ejemplo, para usar el filtro MyClass no hace falta hacer un require_once de MyClass, ya que con el nombre solo ya le alcanza para hacer la comprobación. 2. Cuando se hereda, una clase es del tipo base (su clase) y la de su padre, por lo tanto si soy un Usuario y además heredé de Persona, la validación puede ser filtro(Persona $persona) y ambas serán aceptadas, porque ambos objetos son "personas". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 288. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 288 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 15.Soporte a invocaciones anidadas de objetos retornados En PHP4 estábamos obligados a hacer lo siguiente: $dummy = $obj->method(); $dummy->method2(); Ahora en PHP 5 podemos hacer las invocaciones en cadena de la siguiente forma: $obj->method()->method2(); Es una técnica muy utilizada y se le llama "Interfaces fluidas" (fluent interface), y para aplicarlas deberíamos, a cada método que queremos que se pueda anidar con la ejecución de otro, hacer que retorne la instancia actual con "this". De esta forma podemos anidarlos, ya que la salida de uno es la misma instancia que se va a aplicar en siguiente método. Retorno la misma instancia del objeto donde estoy parado dentro de un método que normalmente no retornaría nada. Idem. Métodos anidados, siempre aplicados a la instancia "usuario". SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 289. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 289 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com ¡No abuses de las interfaces fluidas! Aunque esta técnica de simplificación es muy usada (Java, frameworks de javascripts y PHP, etc) y puede sernos de utilidad, el abuso de este tipo de codificación puede "oscurecer" el entendimiento del código, ya que si anidamos 10 métodos en una sola línea, al final, no sabremos qué hace. Sugerencias: implemerlo en métodos simples, donde antes no retornaban nada, aprovecha y retorna un this y solo lo usas cuando realmente lo necesites y veas que simplifique. En lo posible anida siempre el mismo objeto. No pases de 3 o 4 anidaciones por línea, y trata de usarlo en lugares puntuales, no hagas un sistema que predomine esta codificación o estarás condenado a pasar el resto de tu vida en el infierno de los programadores! (según me han comentado, te tienen 24 hs al día programando POO con COBOL ) SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 290. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 290 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 16. Iteradores PHP5 permite ahora que las colecciones de una clase puedan ser iteradas a través de la misma clase con solo cumplir con una interface, así, con un simple foreach podremos recorrer los valores de un objeto: No es algo que necesitemos hacer regularmente, pero es importante saber que si nuestra clase solo esconde una colección, tal vez esta sea una forma más simple de acceder a la misma, o al revés, darle a una colección de objetos más funcionalidad que un simple array (observar que la interfaz define muchos comportamientos). SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 291. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 291 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com 17. __autoload() Es muy común que debamos incluir al principio de nuestra clase toda una serie de require_once de clases que necesitamos para trabajar. PHP5 ahora incorpora una función que permite definir un simple algoritmo de búsqueda de clases que se ejecutará siempre que nuestro fuente intente hacer un "new" de una clase (automáticamente la función recibirá por parámetros el nombre de la clase que intentamos instanciar, el resto lo definimos nosotros). function __autoload($class_name) { require_once($class_name . "php"); } $obj = new MyClass1(); $obj2 = new MyClass2(); No siempre es tan útil como parece Aunque a veces hacer "todo dinámico" no siempre es bueno, menos para la auto-documentación del código (ya que es útil saber claramente que tiene que requerir nuestra clase), cuando las estructuras de directorios son complicadas, esta función puede no sernos útil, o hasta generar una pequeña "sobrecarga" si por cada vez que intenta encontrar una clase tiene que buscarla de forma recursiva dentro del directorio de nuestra aplicación. Para usar, pero en situaciones concretas y muy simples. Nota final del Anexo En sucesivas versiones se irá ampliando esta sección con más comentarios sobre las nuevas características de PHP5 como lenguaje POO. SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 292. Anexo II: Recopilación de “Hacer un programa a partir de unas FRASES especificaciones y caminar sobre el agua "Los programas deben ser escritos para que son cosas muy simples, siempre y cuando la gente los lea (entienda) y solo ambas estén congeladas.” incidentalmente para que los ejecuten las maquinas" "una de cada 10 personas nace con un Abelson / Sussman talento innato para programar, para entenderse con las computadoras de una manera mágica e increíble.... Si hubiese preguntado a la gente qué es lo lamentablemente los otros nueve creen que quería me habrían respondido que tener ese talento y por eso tenemos caballos más rápidos - Henry Ford carreras de ingeniería de software y libros como este" (se puede aplicar cuando decimos “y por qué no le preguntamos al usuario "Un sistema exitoso se mide por su cantidad exactamente qué quiere?”) de usuarios, no por su supuesta calidad" "Si quieres ganar dinero programando, solo escucha a alguien desesperado con un gran "Pregunta: ¿Cómo se atrasa un año un problema, necesitado por una solución y proyecto grande de software? Respuesta: con dinero" Un día a la vez." "Si quieres ser pobre programando, Fred Brooks escucha a todos los que te pidan un PEQUEÑO PROGRAMITA, que es MUY FACIL de hacer" "La historia de la programación es una carrera constante hacia mayores niveles de abstracción"
  • 293. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 293 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "La programación puede ser divertida, al "Si automatizas un procedimiento igual que la criptografía; sin embargo, desastroso, obtienes un procedimiento ambas no deberían combinarse" desastroso automatizado" -- Rod Michael "El software es como la entropía: difícil de atrapar, no pesa, y cumple la Segunda Ley A lo cual yo diría dado el fanatismo de los de la Termodinámica, es decir, tiende a programadores novatos por priorizar incrementarse" “optimización de código” a funcionalidad de -- Norman Augustine código "La imaginación es más importante que el "Si optimizas un procedimiento desastroso, conocimiento. El conocimiento es limitado, obtienes un procedimiento desastroso mientras que la imaginación no" optimizado" -- Albert Einstein -- Rod Michael "Una de las cosas más fascinantes de los "Ley de Alzheimer de la programación: si programadores es que no puedes saber si lees un código que escribiste hace más de están trabajando o no sólo con mirarlos. A dos semanas es como si lo vieras por menudo están sentados aparentemente primera vez" tomando café, chismorreando o mirando a -- Via Dan Hurvitz las nubes. Sin embargo, es posible que "La simplicidad llevada al extremo se estén poniendo en orden todas las ideas convierte en elegancia" individuales y sin relación que pululan por -- Jon Franklin su mente" -- Charles M. Strauss "Comentar el código es como limpiar el cuarto de baño; nadie quiere hacerlo, pero el resultado es siempre una experiencia más agradable para uno mismo y sus invitados" -- Ryan Campbell "Está bien investigar y resolver misteriosos asesinatos, pero no deberías necesitar hacerlo con el código. Simplemente deberías poder leerlo" -- Steve McConnell SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/
  • 294. Programación Orientada a Objetos en PHP5 SURFORCE / FORMACIÓN 294 de 294 Edición: Julio 2009 / Usuario: Juan Zapata www.surforce.com "Todo el mundo sabe el peligro de la desarrollo" optimización prematura. Pienso que -- Tom Cargill deberíamos estar igualmente preocupados "Depurar es al menos dos veces más duro con el diseño prematuro, es decir, el hecho que escribir el código por primera vez. Por de diseñar demasiado pronto lo que un tanto, si tu escribes el código de la forma programa debería hacer" más inteligente posible no serás, por -- Paul Graham definición, lo suficientemente inteligente (haciendo referencia al desarrollo evolutivo) para depurarlo" -- Brian Kernighan "Por norma, los sistemas software no funcionan bien hasta que han sido utilizados y han fallado repetidamente en Fuente: entornos reales" -- Dave Parnas  101 citas célebres del mundo de la "Cuando se está depurando, el informática programador novato introduce código correctivo; el experto elimina el código  Otras 101 citas célebres del mundo defectuoso" -- Richard Pattis de la informática "La mayoría de ustedes están familiarizados con las virtudes del programador. Son tres, por supuesto: pereza, impaciencia y orgullo desmedido" -- Larry Wall "El buen código es su mejor documentación" -- Steve McConnell "Cualquier código tuyo que no hayas mirado en los últimos seis meses o más es como si lo hubiese escrito otro" -- Eagleson's Law "El primer 90% del código corresponde al primer 90% del tiempo de desarrollo. El 10% restante corresponde al otro 90% del SURFORCE | mail: info@surforce.com | web: http://www.surforce.com Licencia: http://creativecommons.org/licenses/by-nc/3.0/