¿Alguien tiene ejemplos de programas POO?
Rafael Villar Burke
pachi en rvburke.com
Jue Nov 30 05:51:23 CET 2006
Jesus Rodriguez wrote:
> Buenas!
>
> Estoy aprendiendo la POO pero aún me cuesta diseñar los programas.
Es normal, lo más difícil es ir adquiriendo la intuición y las
herramientas mentales para modelizar adecuadamente los problemas.
> Me gustaría que me explicaseis que debería de hacer desde que leo el
> enunciado de un problema hasta que todo está bien.
Yo te recomendaría usar una metodología ágil. Además del artículo de POO
que has visto estoy preparando uno sobre Desarrollo guiado por pruebas
(o TDD por las siglas en inglés), que se correspondería con lo que te
comenta Chema de la refactorización, con el añadido de una metodología
para el diseño e implementación del código incial. Está pensada para no
ocurra lo que te pasa ahora, que te enfrentas a cómo evolucionar el
código sin romper todo o partir de cero.
Mírate http://es.wikipedia.org/wiki/Tdd
> Soy autodidacta, así que me resulta todo un poco más complejo.
>
> Hoy hice un programa básico.
>
> Se trataba un un simulador de un cajero del banco (aunque en vez de
> insertar
> tarjeta de credito, pues pide login y pass), así que logueas y una vez
> dentro pues puedes retirar dinero, ver tu capital y hacer transferencias.
Esta es una descripción general del sistema, pero demasiado esquemática.
Juan Carlos, sábiamente, te recomienda que generes más 'casos de uso',
es decir, escenarios que te permitan barrer de forma más completa el
espacio del problema (http://es.wikipedia.org/wiki/Casos_de_uso) para
poder llegar a conceptualizarlo adecuadamente.
Los casos de uso son una manera de abstraer el problema a través de la
descripción e identificación de distintas interacciones, actores, etc,
que pueden implementarse luego como objetos.
> Luego fui escribiendo metodos que iba pensando que me harian falta, por
> ejemplo buscar un login y pass en la base de datos y comprobar si
> existian.
>
> Así que creé una clase login la cual en cada intento de login, llamaria a
> base de datos para que buscara mi login y me retornara pues False o el
> cliente.
Aquí creo que estás usando un objeto por usarlo. En realidad, podrías
usar una función o una secuencia de órdenes en el programa principal. El
problema es que no has conceptualizado bien la relación entre los
objetos que has creado, y cómo cada uno de ellos sirve para
ocultar/encapsular parte de la complejidad del problema. Deberías pensar
más qué papel tiene cada objeto/concepto/actor.
Por ejemplo, viendo los casos de uso podrías imaginar que tienes un (A)
cliente que inicia las operaciones, identificándose y enviando mensajes
a un (B) cajero que es el encargado de solicitar las operaciones. Este
puede conectarse a su central... etc...
> Asi que cree una clase Cliente que sería rellenada con lo que base de
> datos
> retornó a login.
>
> Pero ya empezaban los problemas (ya que de diseño poco) y cuando por
> ejemplo
> sacaba dinero, la msima clase cliente llamaba a la base de datos para
> actualizar la base de datos (asi que volvi a base de datos y escribi el
> metodo de actualizar), luego para las transferencias hice quizas algo más
> feo ejejje, vi que necesitaba algo más, y escribi un metodo en base de
> datos
> para poder buscar un ID y si existia pues le hacia una transferencia,
> pero
> todo dentro de la clase Cliente, cosa que no me gusta.
Has empezado por implementar algunas clases sin hacer un análisis
adecuado del problema, por lo que acaban por mostrar que no lo reflejan
adecuadamente. A partir de la identificación de los actores y las
interacciones existentes puedes pensar en cómo implementar unos objetos
y qué interfaces deben mostrar, es decir, cómo se relacionan con el
resto de componentes y de qué manera puedes reducir al mínimo la
exposición de los detalles internos (http://es.wikipedia.org/wiki/Api)
Aún así, te encontrarás con casos como este, en el que ves que el método
que has implementado en una clase no corresponde a ese lugar, sino a
otra clase distinta o es una función que opera sobre objetos... Ahí es
de mucha ayuda el conocer técnicas de refactorización. Son técnicas para
cambiar la implementación sin modificar la funcionalidad, en pequeños
pasos que no comprometen la estabilidad del programa. Al refactorizar es
frecuente mover métodos entre clases, o convertir parámetros en
atributos y viceversa, dividir un objeto en dos objetos separados....
Al usar objetos también deberías preguntarte exactamente ¿qué datos y
comportamiento quiero encapsular en esta clase?. Es un poco parecido a
¿por qué esta secuencia de instrucciones deben ser una función?. Tienes
que pensar que sentido tiene esa operación... de hecho, seguro que no se
te ocurre escribir un programa con fragmentos arbitrarios reunidos en
funciones que se llaman f1, f2, f3, etc... se trata de darle sentido
desde el punto de vista de la abstracción que hace el programador (las
máquinas se pueden entender bien con diseños más complicados).
Muchas de las combinaciones, esquemas de funcionamiento e interacciones
más habituales se han sistematizado en lo que se conocen como patrones
de diseño. Como bien te han comentado, es algo muy interesante, que te
proporciona herramientas para hablar en términos más abstractos de la
manera en la que funciona un programa, como los ejemplos que te
mencionaban de Fachada (Façade), MVC (Modelo/Vista/Controlador),
sistemas en tres capas, etc... A eso se refiere la expresión de que
debes encontrar la arquitectura del programa. De hecho, los patrones de
diseño (y los casos de uso) los introdujo un arquitecto, para poder
hablar sobre los espacios de una forma más abstracta que con los
términos "cocina", "baño", etc... que son 'implementaciones' muy
concretas de esas ideas más generales.
> No veo facil el empezar el programa tirando codigo, ya que te quedas
> pensando.... bueno y que mas deberia de hacer? y a mitad del programa te
> acuerdas de algo nuevo y lo añades a tu codigo (o parches ahi feo :P), al
> final terminas el programa de una forma mala, no sé, eso de ir insertando
> codigo en ciertos modulos conforme te vas acordando pues me parece una
> guarrada.
> Lo peor es que vas diseñando al vuelo y terminas con una clase "Cliente"
> donde usa base de datos... ¿Acaso vamos a un cajero y tenemos que
> insertar
> los cambios manualmente?
>
> La pregunta es: ¿Alguien podría indicarme los pasos para poder diseñar y
> programar un buen programa?
Lo que has hecho está muy bien. Te has encontrado con los problemas que
debías encontrarte y ya tienes experiencia sobre qué ocurre sin un poco
de planificación previa o sin una metodología para modificar el código
resultante. Ya tienes datos para seguir avanzando ;).
Te recomendaría:
- que empezases por ejemplos menos complejos (con menos actores/objetos)
- que busques información sobre TDD y refactorización.
En mi opinión, siendo autodidacta, no te recomiendo que empieces
aprendiendo metodologías tan formales como las que parten de
especificación de requisitos o diseño de diagramas UML (aunque
entenderlas y conocerlas está muy bien, pero profundizar en su
sistemática me parece excesivo, salvo que vayas a participar en equipos
de programación).
Otra cosa muy buena es leer código de calidad de otras personas. Se
aprende mucho, como con la lista.
En fin... ánimos, porque creo que estás entrando en la parte más bonita
de la programación....
Saludos,
Rafael Villar Burke
www.rvburke.com
Más información sobre la lista de distribución Python-es