Archivo

Archivo para la categoría ‘diseño’

Ejercicios calisténicos para objetos (III)

Viernes, 6 de junio de 2008

La introducción a esta entrada puedes verla aquí. El segundo capítulo, aquí.

2. No utilices la palabra clave else

No utilices la palabra clave else. Si la condición no se cumple, debes salir del método. Esto evitará el famoso código sinusoidal al no permitirse cadenas de elses.

No… no acabo de captar el sentido de este ejercicio. Vamos a ver. "No utilices else". Hmmmm. "Si la condición no se cumple, debes salir del método"… "Salir del método…" ¿Y si no quiero salir? ¿Qué pasa si con el else tengo asociado cierto comportamiento no trivial? Creo que el tema del else tiene que ver más con la implementación de guardias (al estilo del DIseño por Contrato á lá Bertrand Meyer) Aquí sí que creo que se han columpiado. ¿No será mejor decir que tienes que evitar aumentar irresponsablemente la complejidad de tu código? ¿Que con cada if (¡de hecho con cada punto de decisión!) haces más difícil entender tu código?

3. Esconde las cadenas y los tipos primitivos en clases.

Esconde las cadenas y los tipos primitivos en clases. Esto se conoce como "obsesión por las primitivas". Si quieres usar un entero, antes debes crear una clase (incluso una clase interna) para identificar su auténtico papel. Con ello conseguirás código mucho más claro y verificable.

¡Abstrae, maj@, abstrae! Crea un nuevo lenguaje, por encima de C++, C#, Visual Basic.NET, Eiffel, Haskel, Caml, o ensamblador (especialmente en ensamblador ;-) . Deja de hablar de cadenas, de listas doblemente enlazadas, de árboles equilibrados. Las cadenas de conexión a la base de datos ya no existe, la base de datos ya no existe. La web no existe, ni un servicio web, ni la memoria RAM. El lenguaje en el que debes expresarte y el que antes debes construir, que eso es programar, ¡es el del dominio de tu problema! Si tu problema es financiero (¿y el de quién no, en estos tiempos de crisis?), tu lenguaje permite crear una Accion, invocar el método Accion.Comprar(cuantas). Si tu problema es de logística, tendrás clases como Ruta (.Calcular(), .Llegada(), .Salida()…), Camion, Mercancia…

Más aún, ¿de qué tipo declararías una variable que va a guardar un código postal? ¿un número entero? ¿una cadena de caracteres? Nopes, la solución es crear un tipo CodigoPostal para poder hablar en términos del dominio (por ejemplo, CodigoPostal.Provincia(), y así evitarás tener que invocar mil veces en tu código el método Substring(1, 2) sobre la cadena codigoPostal…). Otra cosa es que internamente sea una cadena, o un número. Eso es decisión tuya y secreto que debe guardar el nuevo tipo.

Dos observaciones. Primero, la obsesión por abstraer puede llevarte a modelizar todo el MundoReal™, (y rediseñar Matrix), y a tu jefe puede que no le mole demasiado. Segundo, abstraer no significa necesariamente ser ambiguo. De hecho, una buena abstracción es extraordinariamente precisa.

Seguiremos informando.

diseño, profesión, what is the matrix

Última adquisición: "OO Software Construction" de Meyer

Jueves, 5 de junio de 2008

Por fin llegó. Directamente desde Chicago, y con ciertas muestras de manipulación (imagino que los aduaneros estadounidenses no se fiaban demasiado de que algo que pesara tanto fuera un libro, y abrieron caja y embalaje), ya está en mi mesa.

Me estoy imaginando algunas de las preguntas que os pueden estar rondando la cabeza:

¿Eres del pasado o qué?, ¡Ese libro es la segunda edición de un libro del año 88!

En realidad soy del pasado, todos lo somos, sólo que en Informática y en particular en Programación, cualquier libro que tenga más de dos años nos parece anticuado. Pero si te fijas en el título del libro, no es "Object-Oriented Software Construction with C++", o "… with C#", o "… with C#++ v1.2.1023", ni cualquiera de esos de "Aprenda <EsteLenguaje> en <Random()> Días". Su contenido es aplicable a cualquier sistema orientado a objetos, del año 88 (primera edición), del 97 (segunda edición), o de febrero del 2007 (última impresión, la decimoquinta).

El conocimiento guardado en estas páginas, y las páginas de tantos otros libros "antiguos" es eterno, amigos. Las experiencias de Fred Brooks no se pueden trasladar punto por punto desde su época a la nuestra, desde el desarrollo del OS/360 a los modernos sistemas "web-enabled distributed social-aware scalable user-centered", pero la esencia de esa experiencia sí que lo extrapolable a lo que ahora construimos. Devaluar un artículo como "On the criteria to be used in decomposing systems into modules", de David L. Parnas porque fue publicado en 1972, o desechar el conocimiento proporcionado por el mismo Fred Brooks en "The Mythical Man-Month" porque dirigió el proyecto OS/360 a finales de los años 60 no tiene demasiado sentido (o si lo tiene, el siguiente en caer debería ser Aristóteles, por viejuno).

¿Acaso no sabes ya cómo se construyen sistemas orientados a objetos, que tienes que comprarte ese libro?

Hombre, a ver, algo sé, pero (1) hay que cosas que no sé, así que leer nunca viene mal, (2) hay cosas que sé, pero con el paso del tiempo, se van degradando, se van difuminando, y no está de más pegarles un refresco, (3) en el caso extremo, tras la degradación, viene el olvido, y entonces sí que viene bien re-leer, y (4) hay cosas que leí hace 10 años que ahora "suenan" distinto. Un libro siempre debe tener una penúltima oportunidad de ser leído.

Sólo a ti se te ocurre leer un tocho así, y encima en inglés, ¿has pensado en ingresar en algún centro psiquiátrico?

No, francamente no. El loco deja de estarlo cuando asume su locura como su forma de vida. Además, la locura, como el pecado, siempre está en el ojo del que mira.

Perdón, ¿la calle Guzmán el Bueno?

Dos manzanas más abajo, a la derecha…

diseño, en busca de mis valores, mens sana, ocio, profesión

Refactorización

Jueves, 29 de mayo de 2008

Degraciadamente, en según qué ambientes, el concepto de refactorización está condenado al fracaso desde su misma base, su propia definición:

In brief, refactoring is the gradual improvement of a code base by making small changes that don’t modify a program’s behavior, usually with the help of some kind of automated tool.

("Brevemente, la refactorización es la mejora gradual del código fuente por medio de pequeños cambios que no modificar el comportamiento del programa, normalmente con la ayuda de algún tipo de herramienta automatizada")

Desde el punto de vista técnico, la idea es estupenda. Mejorar el código sin modificar el comportamiento del programa ¡Eureka! Desde el punto de vista de gestión, la idea es indefendible. Mejorar el código sin modificar el comportamiento del programa ¡Herejía!

— ¿Quiere eso decir que el usuario no va a obtener ningún valor añadido por la inversión en tiempo que vas a realizar?— dijo el jefe. [N. del T.: "Eso suena a que estás perdiendo el tiempo."]

— Sí, bueno, o sea, no, quiero decir que el usuario no va a obtener nada nuevo, sólo que cuando en el futuro pida algo nuevo, nos resultará más fácil adaptar el sistema.— contestó el ingeniero, mientras pensaba: "Mejor no te digo nada de aumento de la entropía del sistema, o pensarás que estoy más loco de lo que estoy de verdad".

— Ya… Esto… Verás, creo que es más importante que te dediques a tareas que incrementan el valor que el usuario obtiene de tu trabajo. Luego, cuando haya tiempo, te dedicas a "mejorar"— argumentó el jefe. [N. del T.: "Deja de mamonearme y ponte a currar de una vez"]

— Es que si no mejoramos ahora, cada vez será más difícil hacerlo después. Aunque el usuario no lo vea, las modificaciones mejoran nuestro tiempo de respuesta en el futuro, y con ello su satisfacción.— el ingeniero intentaba contraatacar, usandotérminos sencillo que pudiera entender.

— Mira, es mejor que te dediques a proporcionar valor al usuario.— sentenció el jefe [N. del T.: "Que te calles, chitón, shhh, www.shhh.com..."]

— Lo que digas. [N. del T.: "Haré lo que considere necesario para facilitar mi trabajo y evitar que el sistema llegue a un estado de parálisis funcional"]

¿Y tú? ¿Refactorizas?

¿Y lo sabe tu jefe?

diseño, profesión

Ejercicios calisténicos para objetos

Sábado, 10 de mayo de 2008

Acabo de leer un post de Andrew Binstock al que he llegado saltando de aquí para allá mientras procrastinaba un poco. Andrew leyó en "The ThoughtWorks Anthology", uno de los últimos libros de la serie "Pragmatic Programmers" un capítulo dedicado a la "calistenia para objetos" (Object Calisthenics) escrito por Jeff Bay.

La palabra es un poco rara así que he investigado un poco sobre ella.

Calistenia f. La calistenia es el ejercicio físico destinado a desarrollar las fuerzas musculares.

Es una palabra que ha entrado en el castellano de la palabra inglesa callisthenics, y estos del griego καλλος (kallos = hermoso), y σθενος (sthenos = fuerza).

En realidad creo yo que el autor no se refiere a la calistenia de los objetos, sino la del programador. De hecho, las normas no son para los objetos, sino para los que los escriben. Los ejercicios  son nueve, y los resumo a continuación.

1. Usa sólo un nivel de indentación por método. Si al escribir un método necesitas un nivel más, significa que tienes que crear un nuevo método al que llamarás desde aquél.

2. No utilices la palabra clave else. Si la condición no se cumple, debes salir del método. Esto evitará el famoso código sinusoidal al no permitirse cadenas de elses.

3. Esconde las cadenas y los tipos primitivos en clases. Esto se llama "obsesión por las primitivas" y no tiene nada que ver con las féminas de Atapuerca. Significa que si representas un código postal como una cadena de 5 dígitos, debes crear una clase CodigoPostal que esconda la cadena.

4. Utiliza sólo una instrucción punto por línea. Eso significa que te tienes que OlvidarDe.Llamar().AUnMetodo().TrasOtro() en la misma línea y UtilizarSolo.UnaLlamada()

5. No abrevies los nombres. Este punto no lo he entendido, pero parece ser que favorece este tipo de llamadas => Alumno.Matricular(), frente a este otro => Alumno.MatricularAlumno(). Como no lo he entendido muy bien lo cito y pido vuestra opinión:

Don’t abbreviate names. This constraint avoids the procedural verbosity that is created by certain forms of redundancy –if you have to type the full name of a method or variable, you’re likely to spend more time thinking about its name. And you’ll avoid having objects called Order with methods entitled shipOrder(). Instead your code will have more calls such as Order.ship().

6. Haz que las clases y los paquetes (á la Java) sean pequeños. Por lo visto la heurística es no más de 50 líneas por clase y no más de 10 clases por paquete, lo que favorece mantener la cohesión y el acoplamiento controlados. De gratis, las clases te cabrán en la ventana del IDE.

7. No utilices ninguna clase con más de dos variables de instancia. Opina Andrew que esta es quizá la más dura de seguir, Según Bay, si tienes más de dos variables hay motivos para pensar en agruparlas en otra clase (de dos en dos, claro está). Como bien apunta un anónimo, lo tenemos crudo para programar la clase PuntoEnElEspacio, que necesita claramente tres variables.

8. Utiliza colecciones de primera clase. Lo que significa que tu clase Alumnos debe tener una única variable de instancia: una tabla hash, un array, o lo que sea. Pero sólo una variable.

9. No utilices setters, getters o propiedades (¿alguien tiene alguna sugerencia para traducir getter y setter?). Propiedades caca. Por lo visto esta regla favorece la encapsulación, obliga a la implementación de inyección de dependencia, según el principio de "ordena, no preguntes" (tell, don’t ask).

Como yo tengo la misma duda que Patrick Dubroy sobre si esto va de coña o no, me he propuesto analizar cada uno de ellos. Como el artículo puede ser muy largo, voy a dejar cada reflexión en un post distinto, y así también descanso un poquito :-) .

Seguiremos informando.

diseño

La Regla de Thumper

Martes, 5 de febrero de 2008

Magnífica regla, en la línea de la Regla lo lo Simple (¿o es lo perfecto?).

La Regla de Thumper dice lo siguiente:

Si no puedes decir nada agradable, entonces no digas nada de nada.

¡Ay!, ¡estas frases que son destilados de sabiduría!

diseño

Modelos en arcilla

Martes, 11 de diciembre de 2007

Me ha gustado mucho la comparativa que ha hecho Doods entre la industria del automóvil y la producción de software. Producir software no es como esas líneas de dedicados robots y humanos especializados, en las que es fácil determinar cuántos coches (idénticos, bien definidos…) salen por hora de la factoría. En realidad, es más parecido al tipo que se encarga de hacer el modelo en arcilla:

“Have you seen a car ad that shows a design studio with a clay mock-up? That’s like software development. The guy on the factory floor can easily know how long it takes to assemble an automobile. It’s much more difficult for the guy sculpting clay to predict how much work and how many revisions it will take to get to the final design”.

Esto confirma la idea acerca de la auténtica esencia del software: la información y el conocimiento. De hecho:

“Software development is an exploration. It’s learning about the problem domain, the customer’s needs, and how a solution can be realized with the available resources. Learning requires space and time for experimentation and failure“.

¡Es algo fundamental! ¡Nadie aprende por acertar! Si ahora aciertas, es porque antes has fallado de muchas maneras distintas. ¿Por qué no aprendemos a fallar? Creo que tiene que ver con que nos han educado para esperar un castigo si hacemos algo “mal”… No hay que castigar si uno se equivoca… Hay que castigar cuando uno se equivoca reiteradamente. Y ni siquiera en esos casos. Defiendo en esos casos una buena herramienta: enseñar.
Y ya para terminar, categórica, la auténtica definición de “manufactura del software”:

“Software manufacturing, at its least adorned, is a file copy operation”.

Ahí queda eso [las negritas son mías].

diseño, profesión

Sencillez (aparente)

Jueves, 6 de diciembre de 2007

No sé dónde lei que cuanto más sencilla es una aplicación para el usuario, más complicado es para los desarrolladores construirla. Y también es cierto que cuando un stakeholder te presenta sus necesidades, el primer modelo mental que se construye es francamente sencillo (o sea, poco detallado).

Cuando por fin vas pasando de un análisis del problema al diseño de una solución, el número de detalles aumenta naturalmente. Este tipo de detalles tiene muchas veces que ver directamente con el problema y siempre con los requisitos del usuario, tanto funcionales como no funcionales. Así, lo que antes era sólo introducir información se transforma en un conjunto de decisiones relativas a la validez de esos datos, a su tipo, a la estructura entre ellos, a qué hacer cuando los datos son parcialmente incorrectos. Sin decir nada sobre los mecanismos de seguridad, que determinan quién puede introducir qué datos y cuando. ¿Habrá un proceso de introducción por una clase de usuarios y otro de validación por parte de otra clase distinta? ¿Se querrá registrar quién introdujo la información? ¿Sólo la última modificación, o un histórico de ellas?

Para los que diseñamos y construimos sistemas de gestión, un síntoma de este Big Bang que transforma un problema primordial en un universo de soluciones galácticas (y el energético proceso que pasa de una a otra) aparece cuando tenemos que agregar “un campo más”. Un campo más, es revisar desde la base de datos hasta todas las capas de presentación (incluyo informes), qué partes se ven afectadas… Sí, es cierto, es la más fácil de las modificaciones… :-) Imagínate cualquiera otra…

Por cierto, me niego a traducir “stakeholder” por tenedor de apuestas. Creo que la traducción más cercana podría ser “implicado en” o “interesado por” un proyecto. ¿Alguien tiene alguna otra sugerencia?

diseño

"La" manera de hacer las cosas versus "una" manera de hacer las cosas

Lunes, 3 de diciembre de 2007

Lo reconozco, estoy muy negativo. Esta entrada es negativa.

Acabo de leer en el blog de James Fallows una entrada (via raganwald), y comparan la forma en la que unos japoneses repostan un avión, con la forma en la que lo hacen unos chinos. Como bien dice, no es un estudio científico, pero a pesar de ello concluye que:

With usual caveats against sweeping generalization, what this made me think was: Japan is all about the way of doing things. Practice, ritual, perfectionism, as much fanatical attention to the process as to the result. China is all about finding a way to do things. Improvisation, little interest in rules, putting up with whatever is necessary to attain the result.

[El subrayado es mio, las negritas suyas]. Opino que la conclusión puede extenderse también a la idiosincrasia nacional: nos preocupa mucho lo que vayamos a conseguir, pero no tanto cómo lo conseguimos. En el mundillo informático en el que me muevo, el paradigma de “una” manera de hacer las cosas es “pero funciona”, mientras que “la” manera de hacer las cosas ni siquiera se piensa, mucho menos se documenta ni se practica.

No lo veo ilógico. En el ámbito laboral, no prima tanto cómo haces las cosas (la manera en la que haces las cosas), sino qué resultados has conseguido en última instancia. Y en particular, tanto mejor si lo consigues en el menor tiempo posible, aunque eso suponga saltarse pasos “innecesarios” que luegon afectan directamente a la calidad de los resultados, o al (invisible) trabajo que hay que rehacer más adelante debido a la baja calidad de lo producido.

Tom deMarco y Tim Lister ya nos lo adelantaron en su libro Peopleware el año 1999. En su capítulo 4 (Quality, if time permits) nos sugieren que hagamos un experimento. Preguntad por ahí a 100 personas que os digan un país asociado a la alta calidad, y es muy probable que el país sea Japón. Y luego preguntad también por ahí qué país está asociado con una alta productividad. Y es muy posible que el país también sea Japón. ¿Alta calidad y alta productividad a la vez?

A ver si la influencia oriental del Japón se nota más allá de la creciente conversión de la gente al budismo.

diseño

De democratia

Miércoles, 28 de noviembre de 2007

He encontrado dos maneras de hacer que el desarrollo de software se hagan según cierta manera, que vamos a llamar buena (no utilizaré el término mejor). La primera de ellas es utilizar plantillas para crear los distintos artefactos necesarios a lo largo del proceso. De esa forma, siguen una estructura predefinida. Si la plantilla llega al status de “formulario”, entonces el tema es todavía más rápido. Existe un riesgo, que es fácil caer en el diseño por copiar y pegar. Si te das cuenta tarde de que puedes factorizar algo, el trabajo puede ser un tanto tedioso.

El segundo método es elaborar un diseño que obligue a que se utilice una determinada estrategia durante el desarrollo (esto se aplica más a la parte de construcción o codificación). Por ejemplo, con un framework de persistencia que obligue a que todo los accesos a la base de datos, incluidas las consultas, se realicen por medio de procedimientos almacenados, permite que la gestión de permisos o la modificación de la estructura física de la base de datos se pueda cambiar en ciertos casos sin que afecte a la aplicación, además de todas las demás ventajas conocidas del uso de procedimientos almacenados frente al acceso directo a las tablas en seguridad, rendimiento, coherencia de los datos…

Sí, lo sé, suena dictatorial y lo es. Pero no estamos hablando de que un proyecto sea una democracia. Sin control, sin ciertas restricciones, es imposible que llegue a nada. También entiendo que la democracia se puede hacer entre iguales, y no suele ser el caso…

Reconozco que estoy un poco sensible, pero creo que es más bien una reacción natural a la presión que impone el no poder comunicarme como me gustaría…

Creo que seguiré analizando este tema. Este pensamiento es simplemente una explosión, y hace falta destilarlo…

diseño

Martin Fowler

Miércoles, 14 de marzo de 2007

Indudablemente, uno de los ingenieros software que más me ha influido ha sido Martin Fowler. Su forma de razonar un diseño, su manera de expresarlo, y los ejemplos de código presentados para ello han hecho mella en mí.

diseño