Solución Semana 3: "Diseño en 3 capas" (I/III)

Bueno, voy a dar una solución al primer requerimiento del desafío de la "Semana 3" que no necesariamente ustedes debieron acercarse a la versión que voy a presentarles (trato de dar un paso más adelante).

Conceptualmente hablando

Desde nuestros "módulos" (index.php, listado_usuarios.php, consultar_usuario.php y mostrar_usuario.php), ubicados en la raíz del proyecto, debemos asegurarnos que la "dependencia" (flecha punteada) sea solo con el "paquete de presentación" y no con el resto de los paquetes (como se ve en el primer diagrama). Si nuestro sistema está organizado en 3 capas (siguiendo el segundo diagrama corregido, presentado a continuación) la forma de trabajo debería ser siempre:


"módulo" -> "presentación" -> "dominio" -> "persistencia"
  • "presentación": resuelve la interfaz, arma las pantallas, pero si necesita datos pasa a solicitarlos al dominio.
  • "dominio": donde se encuentran todos los objetos que representan la lógica de nuestro universo, de nuestro problema, de nuestro negocio (por eso también se le dice "capa de lógica de negocio"). Por ejemplo, si queremos mostrar un usuario este estará representado como un objeto de tipo Usuario la información para crearlo está en esta capa.
  • "persistencia": si necesitamos "persistir" la información para poder volver a recuperarla en un futuro, es decir, todas las operaciones conocidas: recuperar sus datos, grabar datos o modificar los existentes, eso representa acceder a la capa de "persistencia", quien se encarga de comunicarse con la herramienta de turno (una base de datos, un archivo plano, xml, webservices, etc).
Capas = Responsabilidades

Cada capa tienen su responsabilidad única, concreta, bien definida. De esta forma tenemos a nuestro sistema bien diseñado, dividiendo los problemas en partes diferenciadas. Si hay que modificar o agregar funcionalidades, hay que ir a una capa concreta y no tocar todos los fuentes de nuestro sistema. De la misma forma, si una capa hay que cambiarla por otra, se puede hacer intercambiándolas, o hasta usándolas ambas hasta que una sustituya a la otra, de forma casi transparente.

Si queremos cambiar la estética, solo se modifica la capa de presentación. Si queremos cambiar la lógica del funcionamiento del sistema, la capa de dominio, y si queremos hacer cambios en la forma de almacenar la información, la capa de persistencia.

Nota: no siempre es tan literal, puesto que si agregamos un "caso de uso" a nuestro sistema, deberemos crear la interfaz, reutilizar o crear parte de la lógica del dominio existente, y si no existe, agregar la funcionalidad para persistir el nuevo objeto.

Hay dos frases que entran en juego aquí:
  • "Divide y conquistarás" (frase histórica)
  • "Desarrollar un sistema es, fundamentalmente, un problema de orden" (mía ;-))
Dividir nuestro sistema en 3 o más capas, y cada una resuelva un problema, es justamente eso, trabajar de forma ordenada teniendo el control de lo que sucede.

Cambios a realizar

Claramente se detecta en el diagrama las clases que se está rompiendo el diseño de 3 capas y accediendo a cualquier capa sin ningún tipo de orden. Los fuentes involucrados son: listado_usuarios, consultar_usuario y mostrar_usuario.


Repasando: deberían entrar por la capa de presentación y luego esta capa -y solo esta- acceder a las demás capas.

index.php

  • Siguiendo el diagrama, este módulo se convierte en una clase (así tratamos de transformar nuestro desarrollo híbrido en un sistema 100% Orientado a Objetos, objetos que se comunican con objetos), por lo que habría que encapsular todo en una clase (se obtiene la estructura interpretando el diagrama).
  • La dependencia es correcta puesto que apuntaba únicamente al paquete de presentación.
  • No cambiamos de nombre el fuente a Index.class.php porque romperíamos el estándar y nuestro servidor no encontraría el index.php, pero internamente sí la convertiremos en una clase (Nota: esto es una convención que se me ocurrió crear, no necesariamente encontrarán esta forma de trabajo explicada en ningún libro).

listado_usuarios.php

  • Este es el primer fuente que muestra claramente la dependencia contra dos paquetes (presentación y dominio) cuando debería ser solo con el primero, y luego pasar de presentación a dominio. Esto se lee en PHP simplemente viendo la sentencia require, require_once, include o include_once (aquí ya estoy respondiendo la pregunta del cuestionario).
  • Dijimos que todo iban a ser clases, entonces, creamos una clase ListadoUsuarios
  • Mantenemos el mismo nombre, rompiendo la nomenclatura porque así lo necesitamos ahora para poder acceder desde http://localhost/surforce-proyectobase/listado_usuarios.php (no usamos ListadoUsuarios.class.php por la misma razón que no decidimos hacerlo con index.php).
  • Debemos modificar PresentacionFachada::listarUsuarios del paquete presentación para que resuelva internamente las invocaciones a la capa de dominio. Simplemente evitamos tener que hacerlo en el módulo y estas se esconden dentro del paquete que corresponde.

presentación/PresentacionFachada.class.php

  • El método listarUsuario deja de recibir por parámetros los usuarios y ahora internamente llama al dominio para solicitarlos. El módulo ni se entera (no debe) pues es una responsabilidad de la presentación obtener los datos del dominio, el módulo solo debe ejecutar la acción de la capa de presentación, el resto, un problema interno que no me corresponde enterarme. Es importantísimo entender esto para que nuestro sistema esté "desacoplado" y pueda ser "reutilizable".

mostrar_usuario.php

  • Similar al caso anterior, creo una clase, saco el código del dominio del módulo y lo muevo a la capa de presentación, y me quedo solo con llamadas a la capa de presentación.
  • En presentación modifico para que invoque ahora al dominio (como decía anteriormente, simplemente es pasar la lógica del módulo al paquete presentación).
Hasta aquí solucionamos el problema de "las 3 capas rotas", ahora, terminemos de corregir para que cada módulo sea una clase:

consultar_usuario.php

  • Similar a los casos anteriores, encapsulo todo en una clase y luego invocamos el método que inicia la acción (método ejecutar).
Fin de la parte 1 del desafío "Semana 3"

Pronto, un poco más, un poco menos, es lo que se esperaba de la "parte 1".

Dudas y consultas, en los comentarios de esta entrada. ;-)

5 comentarios:

paopao1983 dijo...

Ups! parece que mi trabajo estuvo bastante incompleto, no habia entendido que debia pasar a clases los "módulos" (index.php, listado_usuarios.php, consultar_usuario.php y mostrar_usuario.php)... parece que esto puede estar interfiriendo en el hecho de aun no tener completamente clra la semana 4... oh My dear good.. :-( parece que estoy muy deficiente.. bueno estaré pendiente del resto...

enrique_place dijo...

Estimada Paopao:

No se abrumen, la idea fue siempre plantearles problemas que los superen y yo entregarles una solución un poco más amplia y completa.

Lo importante es el esfuerzo que deben poner para resolver los problemas, los caminos que toman, para luego entender y comparar a través de un "ejemplo base" que les planteo.

Nunca les pedí algo 100% completo, solo que lo intenten y en base a sus debilidades yo me encargo de "construir puentes" hacia el conocimiento, mi versión, no una "verdad única" (que ustedes pueden estar de acuerdo o no, perfectamente discrepar con ella).

Sergio Lopez dijo...

mm tenia mas o menos la idea... ni modo, el tiempo me ha comido, esperare el desafio que incluye todos los desafios, si se hara esto ?

"En este momento solo participarán los que han entregado los trabajos de la Semana 2 y Semana 3, y los restantes desafíos que seguiré publicando durante el mes de marzo. Posteriormente, se volverá a abrir el registro de usuarios y cambiaremos la forma de integrarlos a los equipos de trabajo existentes. Muy probablemente se les solicitará una tarea puntual que resumirá todo el proceso de desafíos y si la aprueban quedarán clasificados para participar como desarrolladores o líderes."

Saludos

ATTE
Sergio López

enrique_place dijo...

Estimado Sergio Lopez:

> mm tenia mas o menos la
> idea... ni modo, el tiempo me ha

Eso es importante, con intentar bastaba para seguir en carrera.

> comido, esperare el desafio que
> incluye todos los desafios, si se
> hara esto ?

Sí, pero debes entender que vamos lento y que algunas actividades están demoradas.

Por lo pronto este mes siguen los desafíos y el mes que viene iniciamos el trabajo en equipo.

Tengo que ver también como responden los líderes.

Alvaro dijo...

Hola Enrique! en primer lugar, enhorabuena por el blog. Nos ayuda bastante al resto de los mortales!

¿Podrias colgar los ficheros de ejemplo de este articulo?

Un saludo. Alvaro

Entradas populares