Foros del Web

Foros del Web (http://www.forosdelweb.com/)
-   Frameworks y PHP orientado a objetos (http://www.forosdelweb.com/f68/)
-   -   Duda con interface en php5 (http://www.forosdelweb.com/f68/duda-con-interface-php5-440249/)

zsamer 03/11/2006 17:43

Duda con interface en php5
 
Hola,

he buscado y leido bastante en la web sobre interfaces en php5, pero aun no me queda claro en que caso utilizarlas, para que sirven en la practica y su concepto en general, en todos los articulos sobre interface hablan que se utilizan para la reutilización de código y heredar pero no lo capto en los ejemplos que exponen.

Gracias ojalas que alguien me ilumine con respecto este interesante concepto oop.

salu2

enriqueplace 03/11/2006 22:12

Las herencias de clases definen el "qué son" y las de interfaces agrupan clases que definen el "qué hacen".

Cuando agrupas por herencia hay una relación de parentesco, pero con las interfaces agrupas cosas que "hacen cosas similares" como una interfaz "imprimible" que todos tus objetos deberían implementar para poder pasar por la impresora (les estás diciendo de alguna forma que deben cumplir con un "contrato de implementación" para poder ser "imprimibles").

O hacer una interfaz "Pelable" para que la implementen las bananas, las manzanas y tu multiprocesadora. Esta última no es pariente de "frutas", pero puede hacer la misma acción que es "pelar".

Esto se relaciona con el polimorfismo, en el sentido que vas a tener un método de una clase, no sé (ya me estoy divagando mucho), cocinero, que pueda pelar cualquier cosa que le den, mientras estas sean "pelables".

Código PHP:

class Cocinero{
   public function 
pelar($elemento){
      
$elemento->pelar();
   }


El "contrato de implementación" se hace cuando haces este "control de tipo":

Código PHP:

class Cocinero{
   public function 
pelar(Pelable $elemento){
      
$elemento->pelar();
   }


Entonces solo pueden entrar los objetos que cumplan con la interfaz.

Si lo quieres ver de otra forma, se podría hasta decir que las interfaces son una extensión conceptual de la herencia (por lo que puse al principio).

Y finalmente, y esto es clave en entornos como Java, las interfaces permiten pasar del estilo de diseño "orientado a la implementación" a uno "orientado a la interfaz", donde todas las clases acceden a servicios a través de interfaces que son implementadas por clases concretas. Y al no depender de clases concretas (solo de entidades abstractas) nuestro diseño será más reutilizable que el anterior.

Este último párrafo debería ser un "mantra" de los desarrolladores y repetirlo ni bien nos levantamos y ni bien nos acostamos :-)

zsamer 04/11/2006 10:26

Gracias Enrique, me quedó más claro, aunque me es dificil aplicar el concepto en la practica.

Felippe 09/11/2006 14:05

Hola zsamer:

Tal vez este pequeño ejemplo, te ayude acomprender el concepto de 'interface':

Código PHP:

interface Mascota{
 public function 
hablar();
}

class 
Gato implements Mascota{
   var 
nombre;
   public function 
hablar(){
       print (
"Miau, Miau");
   }
}

class 
Perro implements Mascota{
   public function 
hablar(){
       print (
"Guau, Guau");
   }


Si observas el ejemplo, comprenderas que la clase Perro y Gato, definen especificamente 'EL COMPORTAMIENTO DE LA CLASE', en cambio el 'interface' solamente señala lo que la Mascota 'debe hacer', es decir declara el comportamiento para todas la clases que quieren ser de tipo Mascota.

Espero te sea de ayuda. Un saludo.

zsamer 09/11/2006 14:16

gracias,

Si bien la interfaz define comportamientos que debe tener la clase que la implementa, no le encuentro otra utilidad y sobre todo en el aspecto de reeutilización de código.

¿cómo puedo reutilizar más mis codigo y mejorar el diseño de mis clases y optimizar estas con las intefaces?

¿más alla de definir comportamientos tiene otras ventaja al utilizarla?

Felippe 09/11/2006 15:10

Que tal este ejemplo:

Código PHP:


interface VO{
   public function 
insertarDatos();
}

class 
Persona implements VO{
    private  
$nombre;
    private  
$apellidos;

    public function 
insertarDatos(){
        
$query "INSERT INTO personas values ....";
        
// codigo adecuado para insertar en la tabla 'personas'....
        
return 1;
    }
}

class 
Proveedor implements VO{
    private  
$nombre;
    private  
$direccion;

    public function 
insertarDatos(){
        
$query1 "SELECT count(id_proveedor) from proveedor ...";
        
// codigo adecuado para buscar algun proveedor con el nombre '$nombre' ....
        
        
if( <no-existe> ){
            
$query1 "INSERT INTO proveedores VALUES...";
            
// codigo adecuado para insertar en la tabla 'proveedores'....
        
}else{
          return -
1;
        }
    }
}

class 
Transaccion {
    ... 
    
/* @param un objeto de tipo VO */
    
public function procesar$vo ){
       ...
       
$vo->insertarDatos();
    }


En este caso, a la clase Transaccion, en el método 'procesar', no le importa 'CÓMO' el objeto '$vo' lleva a cabo su tarea, solo le importa que "sabe insertar datos" (observa el comportamiento especifico de las clases Proveedor y Persona). Es decir, si conoces que algun objeto 'sabe hacer algo' puedes hacer que otras clases futuras, empleen ese comportamiento sin necesidad tener que hacerlo desde cero.

zsamer 09/11/2006 17:40

gracias, por el ejemplo.

modifiqué la clase Transacción:

Código PHP:

class Transaccion {
    
//... 
    /* @param un objeto de tipo VO */
    
static public function procesar(VO $vo ){
    
//...
       
print $vo->insertarDatos();
    }


entonces el objeto se crearía de la siguiente forma:

Código PHP:

$proveedor = new Proveedor;
Transaccion::procesar$proveedor ); 

esa es la idea?

gracias y saludos

enriqueplace 09/11/2006 20:02

¿Mmm... será por eso que repito constantemente que lo más importante, más que saber en profundidad la sintaxis de un lenguaje, es tener claro los conceptos?

Tu ya conoces la sintaxis, pero no sabes para qué se usa... lee sobre conceptos de POO, que se aplican con cualquier lenguaje OO.

¿Si yo te dije, claramente, para qué sirve la herencia... no te parece que las interfaces extienden de alguna forma su funcionalidad?

Las interfaces se usan para crear el "famoso" concepto de "contrato de implementación". Si tu tienes una clase:

Código PHP:

class Impresora{
   public function 
imprimir(ObjetoImprimible $o){
      
$o->imprimir();
   }


Estás diciendo que tu impresora solo puede trabajar con objetos que "cumplan con un contrato", es decir, que cumplan con las especificaciones de la interfaz ObjetoImprimible. Si implementan la interfaz, están obligados a implementar todos los métodos que ahí aparecen, y si lo hacen, la clase Impresora sabe que puede trabajar con ese objeto, pues ese objeto tiene todo lo que se requiere.

Que es lo opuesto a decir:

Código PHP:

class Impresora{
   public function 
imprimir($o){
      
$o->imprimir();
   }


Donde deberás cruzar los dedos para que quien use esa clase le esté pasando objetos que tengan un método imprimir, porque de lo contrario, tu clase no funcionará.

Con interfaces bien aplicadas robusteces tu diseño.


Ahora, siguiendo con el ejemplo, creamos el contrato:

Código PHP:

interface ObjetoImprimible{
   public function 
imprimir();


Ahora, todo quién quiera imprimir deberá implementar esta interfaz, o conceptualmente, "cumplir con el contrato establecido para poder usar la impresora".

Código PHP:

class Libro implements ObjetoImprimible{
   public function 
imprimir(){
      echo 
"soy un libro";
   }


Otro objeto que quiere ser impreso:

Código PHP:

class Foto implements ObjetoImprimible{
   public function 
imprimir(){
      echo 
"soy una foto";
   }


Forma de probarlo:

Código PHP:


// Funciona
Impresora::imprimir(new Libro());
Impresora::imprimir(new Foto());

// No funciona
Impresora::imprimir(new Curriculum()); 


¿Se entiende? bueno, sobre estos conceptos "aparentemente tan tontos" están basadas arquitecturas completas... como Java.

Busca material sobre el principio "Open/Closed" (Abierto/Cerrado). La primera vez que lo conocí se me cayó una lágrima de la emoción, me sentí iluminado, y dije... ahora veo la matrix ;-)

El principio dice, algo así: "nuestros diseños deben ser cerrados al cambio y abiertos a la extensión".

Traducido sería: el diseño que incluye nuestra Impresora y sus clientes, una vez concluida su implementación, no debería cambiar, porque si lo hace, podría generar un efecto en cadena sobre todas las clases que la usan. Pero se puede extender al permitir seguir agregando clases clientes con solo implementar la interfaz y sin tener que cambiar el código de implementación de la clase Impresora.

Lo que se busca con todo esto es hacer buenos diseños OO para disminuir los costos de mantenimiento, que no debas tocar clases que luego generen impactos en cadena.

Finalmente, muchos principios de diseño te sugieren que no dependas de implementaciones concretas, solo de implementaciones abstractas, y eso solo lo puedes hacer usando interfaces.

Para luego concluir en otro principio, el de "inversión de dependencias", que dice que: "los clientes tienden a ser propietarios de las interfaces y aquellos que ofrecen los servicios las implementan".

En un principio se tiende a pensar que un paquete o capa (utilidades) tiene las clases que implementan servicios (Impresora) y las interfaces de las mismas (ObjetoImprimible), y existirá otro paquete (dominio) que contendrá las clases que serán clientes del primer paquete (dominio -> utilidades).

Pero el principio te dice que es lo opuesto, que las interfaces deberían estar en el paquete cliente, porque así inviertes las dependencias entre ellos, generando que dependa el paquete más concreto del más abstracto, por lo cual genera que sea más fácil reutilizar un diseño de esta forma.

Finalmente, la sintaxis es simple, pero si no tienes los conceptos claros no verás todo el resto.

PD: Yo estoy en pañales y sigo probando e investigando todos los días. Lo que te cuento es moneda común en ambientes más arquitectónicos como J2EE... nosotros somos unos niños en pañales.

Pero podemos intentar aprender de las experiencias de otros.

zsamer 09/11/2006 20:37

Muchas gracias enrique muy interesante el tema de las interfaces y clases abstractas.

ahora me queda mucho más claro.

saludos y gracias nuevamente.

Felippe 10/11/2006 08:01

Excelente la exposicion de Enrique, y gracias por la aclaracion de conceptos de Paradigma OO.

A zsamer, si, comprendiste bien el ejemplo, que lo escribi a la rápida, perdon por el error de sintaxis. Pero la exposicion de Enrique estuvo mejor con mucho.

PD.: Que gusto da ser parte de un foro con personas muy cultas y que humildemente saben aportar. En verdad aprendo mucho en este foro, gracias a todos :arriba:

enriqueplace 10/11/2006 08:31

Bueno, ojo, también tomen todo con una actitud "crítica"... muchas exposiciones contienen "experiencias personales" y también, "opiniones personales". No es sano tomar todo, tal como nos lo presentan, sin cuestionarlo.

No tengo la verdad absoluta y puedo equivocarme, más cuando uno está siempre tratando de aprender (ya lo dije más de una vez, me gustaría tener la calidad y facilidad de implementación que tiene mi amigo GatorV).

Pero trato de basarme en autores reconocidos y darle más prioridad a los conceptos que al lenguaje. Hay muchas cosas que desconozco de PHP y otras que directamente no uso, y nunca uso la memoria, siempre voy a buscar hasta lo elemental al manual (doy prioridad al razonamiento que a la retención en memoria de conocimientos). Siguiendo esa metodología, mañana podría cambiar de lenguaje y seguir trabajando sin problemas.

Muchas veces comento que las cosas que digo son elementales para muchos desarrolladores Java de nivel medio y alto, pero en el ambiente PHP (donde todavía no hemos madurado hacia el concepto de "arquitectura"), "en el mundo de los ciegos puedo ser rey". Debemos cambiar la mentalidad, ahora que existe PHP5 y su sintaxis nos permite hacer muchas cosas que son habituales en Java, debemos "evolucionar", y no quedarnos en la "simple programación scripting".

Existen los "principios de diseño", los "patrones de diseño", existe UML, existen los frameworks, etc. Tenemos que ir subiendo de nivel, no nos podemos quedar en lo elemental.

Después no se quejen 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 desvaloriza como algo menor, todo porque es un "simple lenguaje web".

El "simple lenguaje" lo hacemos todos, al ser "simples programadores PHP", perfectamente podemos tratar de trabajar "más en serio" como lo hacen los "desarrolladores Java", y tratando, con creatividad, de suplir las carencias momentáneas (sí, todavía sigo esperando los "namespace").

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

¿Ustedes que van a hacer? ¿Se quedan donde están o se van a subir al tren? :adios:

PD: De la misma forma, creo que nos hace falta tener más "sentimiento de comunidad", como sucede hasta exageradamente 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 esta migración, pero fundamentalmente, promover el uso de las nuevas versiones del lenguaje, e invitar a usarlo como si fuera una arquitectura (proveedores, desarrolladores, empresas, universidades, etc).

Tenemos que especializarnos y profesionalizarnos, el mundo pide POO, arquitecturas, capas, etc, y habla en UML... vos, en que idioma hablas? :-)

B** 10/11/2006 08:58

Aqui viene mas informacion sobre interfaces y clases abstractas...

GatorV 10/11/2006 09:02

Mi estimado enrique, creo lo que acabas de exponer se deberia de enmarcar al principio de este foro y dejarlo para que todos lo vean, es impresionante la manera en que defines como debemos de avanzar! y no dejar que nos crean "menores" a los programadores en Java/NET, ya que podemos hacer lo mismo y mejorarlo!

:arriba:

zsamer 10/11/2006 11:12

Enrique, comparto cada palabra que has escrito en tu último mensaje, felicito la manera en que has expresado la importancia de profesionalizar el desarrollo en lenguaje PHP hacia una arquitectura POO de calidad, que implemente patrones de diseños, 3 capas (MVC).

A estas alturas PHP a ido evolucionando lo suficiente para desarrollar aplicaciones de gran escala, así como en JAVA o .net, Hoy en día ya existen herramienta que permiten trabajar como "plataforma", en mi caso ya llevo un par de meses en que trabajo con Zend Platform + Eclipse PHPIDE + ZendFramework, estos tres componentes se transforman en una potente plataforma de desarrollo en PHP 5 OOP.

Cita:

Iniciado por enriqueplace (Mensaje 1774424)
¿Ustedes que van a hacer? ¿Se quedan donde están o se van a subir al tren? :adios:

Tenemos que especializarnos y profesionalizarnos, el mundo pide POO, arquitecturas, capas, etc., y habla en UML... vos, en que idioma hablas? :-)

Ya me subí al tren, aunque reconozco que me falta muchísimo por aprender, aun estoy gateando en pañales, me faltan madurar varios conceptos POO, por cierto yo venía del mundo de PHP estructurado, nunca antes había tenido experiencia en POO, y hace meses que comencé estudiar e implementar con el paradigma POO, es decir tuve que aprender desde 0 y todo gracias a verbo googlear y a los grandes personajes de este foro como GatorV, enriqueplace, casuis (que lamentablemente ha estado desaparecido) y cluster (a pesar de que no maneja mucho la programación POO, pero si sabe muchisimo sobre el lenguaje, librerias y técnicas).

saludos

paopao 03/02/2007 18:11

Re: Duda con interface en php5
 
Hola, super interesante lo que han dicho todos aqui :-).

Bueno ahora vengo yo, espero no embarrarla :D.
O.K. partiendo de lo expuesto, yo podría decir que una interfaz puede ser un compendio de funcionanalidades comunes entre las clases? es decir si algunas clases manejan lo que es la búsqueda de algo que son, la muestra de ello, la insersion, eliminacion de algo, se podría colocar en una interfaz, pues estas funciones serían lo que la mayoría de las clases utilizarian en común. Entonces tomando de referencia el ejemplo de enriqueplace se tendría:

class general{
public function buscar($o){
$o->buscar();
}
public function mostrar($o){
$o->motrar();
}
public function insertar($o){
$o->insertar();
}
..... y asi ... etc
}



interface Objegeneral{
public function buscar();
public function mostrar();
public function insertar();
}


class Persona implements Objetogeneral{
public function buscar(){
Algún SETECT....;
}
public function mostrar(){
Sería mostrar lo encontrado....;
}
public function insertar(){
Algún INSERT....;
}
}


class Articulo implements Objetogeneral{
public function buscar(){
Algún SETECT....;
}
public function mostrar(){
Sería mostrar lo encontrado....;
}
public function insertar(){
Algún INSERT....;
}
}


general::buscar(new persona());
general::mostrar(new persona());
general::buscar(new articulo());
general::nsertar(new articulo());
//En esto último entendí que puedo usar la funcion que deseo usar en un momento dado...

Bueno Espero haber dejado claro lo que quiero decir y no haber hecho que lluevan piedras del cielo... :D.

Gracias... :borracho:

migueilichenco 05/02/2007 20:26

Re: Duda con interface en php5
 
interesante aprender los conceptos y llevarlos a la practica, aunque a su ves algo duro al comienzo


La zona horaria es GMT -6. Ahora son las 05:25.

Desarrollado por vBulletin® Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.