domingo, 17 de abril de 2011

Herencia en PHP Parte 1

La herencia es una de las relaciones donde más errores conceptuales se cometen, 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”.

Definición: “es una relación de parentesco entre dos entidades” (una es padre de la otra, una es hija de la otra)

Antes de abordar lo “mecánico de la herencia” quiero destacar lo resaltado :
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”

Metáfora: como en la genética, un padre hereda a su hijo determinadas características que podrá usar a su favor o en su contra. Todo lo que esté en su contra será culpa de nuestro diseño, de cómo habremos hecho al padre y de cuanta información en exceso dejamos que llegue a sus hijos.

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:

Se pueden hacer varias lecturas:

1. Todos los atributos y métodos se heredan del Padre al Hijo, pero…
2. Los atributos y métodos que son de tipo “público” (public) o “protegido” (protected) son visibles directamente desde el Hijo (en el caso particular de “público” son visibles de todos lados, incluyendo desde el exterior del objeto).
3. Los atributos y métodos que son de tipo “privado” (private) se heredan del padre a su hijo pero no son “visibles” de forma directa, solo se podrá hacer a través de métodos del padre que sean públicos o protegidos.

Funcionalmente hablando podríamos decir que un método público “saludar” del padre que su hijo hereda se ejecuta de la misma forma que si el hijo lo hubiera implementado él mismo, solo que el código se encuentra “guardado/almacenado” en el padre.

Hasta el momento tenemos una introduccion basica de lo que es herencia en la programacion orientada a objetos si bien decia no por querer reutilizar codigo tenemos que usar la herencia sino por una relacion que tengas esas dos clases a la cual se asemejen en su comportamiento.

Continuara ....

Comenten no sean bayuncos ...

sábado, 16 de abril de 2011

Los métodos getter/setter o accesores/modificadores

Hoy veremos un tema muy importante en la programacion orientada a objetos en php aunque a simple vista se mire sencillo y sin sentido lo que vamos a hacer mas adelante le hallaremos una utilidad muy grande que son los metodos accesores bien demole con todo pues!!!!

Migremos a la sintaxis de PHP5
PHP5, consciente de este problema, implementa la definición de "visibilidad" de los atributos y métodos, como lo haría Java o .Net. Si hiciéramos una migración "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 los atributos siempre "públicos") usabamos var en PHP4 para declarar propiedades.

Ahora disponemos de las siguientes opciones gracias a la nueva sintaxis: public, private y protected.

Por un tema de principios de la POO los atributos de los objetos deben ser siempre "privados" (concepto "encapsulación": no son accesibles desde fuera del objeto, solo el objeto tiene la potestad de usarlos directamente) y se deberán crear métodos públicos que sustituya una u otra operación, o ambas, cada vez que la situación lo amerite:

  • un método "setter" para "cargar un valor" (asignar un valor a una variable)
  • un método "getter" para "retornar el valor" (solo devolver la información del atributo para quién la solicite).
Los famosos Getter/Setter

Cuando empezamos a aprender a usar Objetos el primer error que cometemos es dejar todos los atributos públicos, lo que permite que cualquier usuario de nuestra clase pueda hacer y deshacer sin control nuestro objeto (modificando y consultando sus valores). Generalmente nuestros objetos deberían contener determinada información que no necesariamente el usuario de nuestro objeto debería saber, porque no conviene, o porque directamente no corresponde y permitirle acceder a la misma es aumentar innecesariamente la complejidad del uso del objeto.

Regla: "Evitar que el objeto muestre detalles de su implementación"
Por ejemplo: si tu sabes que tu objeto "Persona" tiene una fecha de nacimiento y calculas su edad, no deberías poder permitir que alguien "de afuera del objeto" cambie la edad, pues está relacionada con otra información (fecha de nacimiento) y a partir de ella es que se genera (calcularEdad()).

Los detalles del funcionamiento del objeto son internos, y el usuario del objeto (otro desarrollador u otro sistema) no debe ni necesita conocerlos. Por consiguiente ya tenemos otro caso claro, el atributo "edad" no debería poder ser modificado externamente, pero sí consultado cada vez que se necesite.

Si este fuera un atributo público sería imposible restringir una operación y habilitar la otra. De ahí que nace el concepto de "getter / setter", o de "métodos accesores / modificadores", o como muchos autores se refieren a estos métodos especiales como "propiedades" (pero creo que puede generar confusiones con el concepto "atributo", pues muchos otros autores usan las mismas palabras indistintamente). Si tú colocas atributos privados, estos serán solo "vistos / accedidos / usados / modificados" dentro de la propia clase. Si tu quieres que puedan ser accedidos desde fuera de la clase, debes crear métodos públicos que internamente "accedan" a los atributos, pero que los dejarán "resguardados" dentro del objeto.

Errores más comunes que comentemos a la hora de usar metodos accesores

Definir todos los "get" y "set" para todos los atributos existentes. Es casi lo mismo que si fueran todos públicos, careciendo de utilidad. aunque a veces hay excepciones.

Lo habitual es que esto no debería suceder, cuanto más escondamos de nuestro objeto mejor será, pues disminuimos la complejidad de su uso y evitamos que cambie a un estado que no queremos, y cuando menos se sepa de cómo trabaja internamente, más fácil será poder reutilizarlo en contextos distintos (deberá ser raro que debas dejar disponible todo y no existan algunos que sean solo de uso interno). Otro error común es agregarle más lógica que asignar un valor o retornar el valor del atributo. Si necesitas agregarle lógica, ya dejan de ser "get / set", lo cual es mejor que cambiemos de nombre y lo dejemos con los demás métodos comunes de nuestra clase. Por ejemplo: si para cambiar el nombre del usuario, antes de asignar el valor voy a la base de datos y verifico que no exista otro igual, y luego en caso de nombre duplicado genero otro alternativo, etc, preferiría o desglosar el método setNombre en varias llamadas a métodos privados, o directamente crear un método nuevo que se llame cambiarNombre, reflejando un proceso fuera del simple get/set.

Tratemos de de seguir las siguientes reglas
1. Por defecto, atributos privados
2. Usa métodos comunes y no getter/setter
3. Si no queda otra opción, usa solo getter
4. Si no queda otra opción, usa setter

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".

Bien despues de la teoria veamos que ondas bien el ejemplo es sencillo pero nos ayudara a comprender de una forma simple ya que los utilizaremos mas adelante.

primero hay que crear la estructura de los setter y getter tenemos que declarar nuestras propiedades como privadas y luego para no estar escribiendo este codigo repetitivo hay una opcion bastante buena que la encontre en esta web , ingresando el nombre de la propiedad te devuelve su respectivo metodo set y get en php.

enlace

Tenemos que crear una clase y luego nuestras propiedades no olviden de comentar su codigo .

Luego para ocupar esta clase hacemos esto:

Hacemos un require del archivo luego instanciamos y ya podemos usar los metodos de esta clase el metodo set sirve para asignar el valor y el metodo get para obtenerlo. Y el resultado que tenemos es este.

Bien esto ha sido todo para los metodos accesores mas adelante veremos mas utilidades realmente interesantes sobre esto.

Descargar

comenten no sean bayuncos....

viernes, 15 de abril de 2011

Buenas Practicas a la Hora de Vacilar ( de programar)

Bien pues comentare lo que he aprendido y lo que me ha tocado mejorar en muchas ocasiones.

Lo primero es lo primero leer los benditos manuales .

A la hora de comenzar un desarrollo planteate y organizate un esquema de trabajo, por donde comenzarás, y como dividiras las tareas, asigna prioridades y mantén tus ideas lo más ordenadas posible, que para desordenarse ya habrá tiempo!

Haz tu código lo más limpio y ordenado posible

Organiza bien tu código, no dudes en utilizar indentados, saltos de línea y espacios en blanco. si no sabes como pues aca te dejo una web donde solo insertas el codigo y te hace un identado tipo lenguaje C.
Identado

Utiliza nombres de variables representativos, no llames a todo $var1, $codigoRojo, $redCode, si es fecha de inicio, pues ponle $fechaInicio o $fecha_Inicio o como te guste pero siempre representativo y claro, será más facil entenderte y que te entiendan.

Comenta el código, es altamente recomendable que comentes el código, ya que siempre será muchísimo más facil entenderlo, incluso para ti mismo si lo retomas pasados algunos meses.Como dicen que luego de dos semanas es como que nunca escribiste ese codigo asi comentalo.

A la hora de programar primero piensa luego actua no actues primero ya que puede ser que te trabes a medio camino o que estes haciendo mal algun procedimiento y siempre busca alternativas que sean mas optimas.

Otro punto importante es que dividas el trabajo de tu proyecto en partes como algunos framework de trabajo que usan MVC modelo vista controlador aunque no te enfoques en ese patron siempre es bueno ir en orden.No hacer todo de un solo o dejar cosas a medias.

Crea tus estandares o sigue uno por ejemplo los nombre de las clases ponerle un sufijo a cierta parte de clases que represente algo como por ejemplo ProcesosTransaccionales o ProcesosSistema siempre es bueno dividir en modulos tu sistema y el trabajo.

Y algo que tenemos que aprender mucho es que cuando creemos un codigo o desarrollemos X sistema Pensemos a Futuro que ese codigo sea reutilizable o que el sistema sea actualizable o optimizable facilmente.

Si se me escapo uno que es lo mas seguro y crees que es una buena practica compartelo como comentario .

lunes, 11 de abril de 2011

Ejemplo 2 Persona Empresa POO-PHP

Hoy vamos a ver un ejemplo que tiene 2 clases en realidad dos clases separadas ya que no vamos a hablar de eso ya que es Analisis y Diseño orientado a objetos sera en otra ocasion , seguiremos viendo como trabajar POO con PHP.

La idea de cada tarea es aplicar y extender los conocimientos que se debieron haber adquirido con la lectura de los capítulos anteriores.

  • A partir de las clases UML se deben generar siempre archivos aparte, por clase, con la nomenclatura Persona.php y no persona.class.php o persona.php (debemos usar el Estándar de Codificación de Zend)
  • Las llaves “{}” van abajo solo en las clases y métodos, para ningún caso más, ni if, ni while, etc (estándar Zend)
  • Los atributos y métodos privados 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.
  • Mi sugerencia es no hacer mucho uso de los _set y _get que incorpora PHP5, ya que en la mayoría de los casos –según lo que he leído en internet- debilitan los diseños al generar efectos de “atributos públicos”. No siempre lo genérico es bueno, como en este caso.
  • Los atributos deben iniciar siempre en minúsculas, igual que los métodos
  • No es necesario especificar el constructor del diagrama si este no aporta nada relevante.
Aplicación del “Principio KISS” “mantenlo simple estúpido”

Si en una empresa/proyecto para hacer un sistema cada desarrollador (con toda la mejor voluntad del mundo) agrega un “extra” y trata de hacer la “super clase” (agregar funcionalidad no solicitada), la complejidad aumentará exponencialmente.

Es recomendable ajustarse a los requerimientos, a menos que estos digan que deben cubrir todos los posibles errores, situaciones, etc, pero de todas formas habrá que definir un criterio o un límite.

Recuerda: un diseño está atado siempre a un contexto, si cambia el contexto, muy probablemente deberá cambiar el diseño. No existen diseños que sirvan para absolutamente todos los contextos posibles, por lo tanto, es recomendable hacer un diseño concreto para un contexto concreto.


Sugerencias para enfrentar los diseños

En general, tratar de:
  • Empezar a pensar el diseño a partir de los objetos de más bajo nivel (los más simples) y en ese momento “olvidarse del bosque” (así no se pierde el foco de lo que se está tratando de abstraer, el objeto concreto como entidad independiente).
  • •Siempre cuando diseñen una clase, “pararse literalmente sobre ella” razonando qué es lo que debería ver o conocer esta, sin entrar a pensar qué es lo que deberían hacer las demás clases. Tan importante como diseñar qué hacen es entender qué no deberían hacer.
  • Seguir el principio de diseño OO: “Una clase, una única responsabilidad”, si tiene más de una responsabilidad, debe estar haciendo más de lo que le corresponde, y deberá descomponerse en otra clase.
  • Finalmente, con él o los objetos de más alto nivel, empezar a interactuar con los objetos de más bajo nivel, sin interesar cómo están construidos por dentro y qué hace su código interno; solo hay que tomar los objetos y pedirles la información o el comportamiento que necesitamos de ellos (“interfaz pública”).
  • Y el más importante de todos, Mantener un “Diseño Simple” en todos los sentidos, evitar complejidad innecesaria. Por ejemplo, puedes tomar la siguiente métrica: si un método no se puede visualizar en una sola pantalla, hay algo que evidentemente está mal y hay que descomponerlo en varios métodos (refactoring), etc.
Bien ahora vamos a ver en si el ejercicio de que se trata de dos clases una que representa a una persona y otra a la empresa lo que buscamos en este ejemplo no es una relacion entre clase y nada de diseño de clase sino que veamos la sintaxis basica de la POO en php y veamos un ejemplo sencillo pero claro.

Bien las clases son estas:

Persona.php
Esta clase solamente asigna los valores predefinos a las variables privadas de clase para luego invocar ese metodo.

Empresa.php
Esta clase es un poco diferente ya que en ella hacemos uso de mas metodos a los cuales invocaremos desde el index php

Hacemos un require para las dos clases y las instanciamos con new y mandamos a llamar la clase con su metodo y tenemos un resultado como el siguiente.

Bien hasta aca hemos visto lo basico de la programacion orientada a objetos como crear una clase declarar atributos en sus visibilidades como private public protected que son las que soporta php tambien la declaracion de un metodo publico y las instancias que hay que crear para llamar a la clase junto con la llamada al metodo.

Descargar

comenten no sean bayuncos

sábado, 9 de abril de 2011

Ejemplo Uso de Clases en PHP

Bien hoy veremos como se implementa una clase ya en codigo primero tenemos que crear un archivo php que llevara codigo html junto con php.

Lo que hara este archivo es capturar la informacion y mandarla a la clase que creamos en el anterior tutorial .Ahora veamos la clase .

Bien como somos desarrolladores ordenados y nos gusta documentar las cosas "ya que despues de dos semanas vemos el codigo y es como que no lo hallamos hecho nosotros jeee" bien esto lo aprendi de java que le dicen javadoc pues aca en php tambien es una buena practica documentar la clase y todos sus metodos como lo vemos en la imagen.

Ahora que hace esa clase pues solo contiene un metodo que recibe un parametro y se lo asigna a una propiedad privada de la clase y lo retorna.

Bien el ejemplo anterio nos devolvera el valor como lo vemos en la imagen.

Es todo es un ejemplo sencillo pero esencial para meterse a este universo de programacion mas adelante veremos ejemplos mas practicos y mas apegados a la realidad.

Descargar archivos.

comenten no sean bayuncos...