Software Design — 2ª edición


Nota a la 2ª edición: el siguiente texto lo redacté en el año 2001. Puse por escrito algunas de mis nociones de aquella época y envié el texto a un colega quien ese año me preguntó mi opinión sobre cómo diseñar software. Por el momento la primera edición no está disponible en línea. En esta segunda edición me tomé la libertad de disminuir un poco el tufo dogmático de la primera edición. Además, agregué referencias a la fecha de algunas páginas en Internet que cambiaron; aunque mantuve las referencias anteriores, quizá por nostalgia. Esta segunda edición tan sólo contiene pequeñas adaptaciones a la primera edición. Muchos de los puntos requieren actualizaciones mayores.

——

Con respecto al diseño de software, que es el aspecto más fascinante para mí de lo que hacemos como programadores profesionales, permíteme comentarte mis impresiones y conclusiones actuales acerca de esta actividad. Por supuesto, estas conclusiones están sesgadas por mi enturbiado entendimiento, pero después de estudiar la experiencia de algunas luminarias en nuestro campo, e intentar practicar sus lecciones, encuentro que dichas conclusiones tienen sentido para mí.

I. El resultado de la actividad ‘diseño’

El resultado material de la actividad de diseño debe ser algo ejecutable. Cualquier cosa menos que eso es pura estimulación mental.

II. Arquitectura de software

Todos los aspectos, de alto y bajo nivel, de nuestro diseño están expresados, implícita o explícitamente, en la arquitectura del software. Aunque “arquitectura de software” todavía es un término difuso, una exposición adecuada de arquitectura de software es la de Philippe Kruchten «The 4+1 View Model of Architecture».

The 4+1 View Model of Architecture

https://www.computer.org/csdl/mags/so/1995/06/s6042-abs.html

IEEE Software November 1995 (Vol. 12, No. 6)

http://www3.software.ibm.com/ibmdl/pub/software/rational/web/whitepapers/2003/Pbk4p1.pdf

http://www.rational.com/media/whitepapers/Pbk4p1.pdf

En resumen, la arquitectura de software considera 5 vistas o categorías, agrupadas por su naturaleza en:

Conceptual:

Vista Lógica (clases, módulos y subsistemas)

Vista Concurrente (procesos y threads)

Física:

Vista de Componentes (medios para empaquetar los elementos de la Vista Lógica: assemblies, DLLs)

Vista Distribuida (comúnmente llamada infraestructura de cómputo: servidores que contienen los elementos de la Vista de Componentes)

Funcional:

Vista de Casos de Uso. Ésta gobierna a todo lo que puede existir en las otras vistas; en otras palabras, nada debe existir si no aporta a soportar la funcionalidad del software

III. El código fuente es el diseño detallado del software

El diseño de alto nivel puede consistir de diagramas que expresen aspectos de las diferentes vistas de Kruchten, pero el diseño detallado es el código fuente. En software, nuestros planos detallados es un documento técnico llamado comúnmente «código fuente». Dichos planos de nuestro producto son entregamos al constructor del producto: el compilador o traductor a código ejecutable.

Philippe Kruchten, Jack W. Reeves y otros tienen algunas ideas al respecto:

What is Software Design? by Jack W. Reeves

http://www.bleading-edge.com/Publications/C++Journal/Cpjour2.htm

The Nature of Software: What’s so Special About Software Engineering? by Philippe Kruchten

http://www.ibm.com/developerworks/rational/library/content/RationalEdge/oct01/TheNatureOfSoftwareOct01.pdf

http://www.therationaledge.com/content/oct_01/toc.html

From Craft to Science: Searching for First Principles of Software Development by Koni Buhrer

http://www.ibm.com/developerworks/rational/library/content/RationalEdge/dec00/TheRationalEdgeDec00Issue.pdf

http://www.ibm.com/developerworks/rational/library/content/RationalEdge/jan01/FromCraftToScienceJan01.pdf

http://www.therationaledge.com/content/dec_00/f_craftscience.html

IV. Decidir es diseñar

Diseñar requiere decidir constantemente, diseñar es decidir. Decidir sobre los aspectos del diseño detallado, decidir sobre los aspectos de diseño de alto nivel, e incluso decidir que no vamos a decidir nada todavía sobre alguna propiedad particular del software; es decir, vamos a diferir dicha decisión.

Martin Fowler habla acerca del diseño en:

Is Design Dead?

http://martinfowler.com/articles/designDead.html

What’s a Model For?

https://www.martinfowler.com/distributedComputing/purpose.pdf

http://martinfowler.com/articles/purpose.pdf

V. Diseño estable y emergente

Diseñar requiere consideración de los principios que gobiernan y sustentan la arquitectura de software; como dice Bertrand Meyer, los aspectos a gran escala de la arquitectura de software se encomiendan o están sustentados en los aspectos de bajo nivel o escala detallada (código fuente). Si estos aspectos no obedecen a principios coherentes y de estilo, entonces difícilmente se logran los aspectos a gran escala.

Existe un cuerpo de conocimiento importante acerca de diseño orientado a objetos, con reglas que representan esos principios coherentes y de estilo:

Principles Of Object Oriented Design

http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign

Las recomendaciones del maestro Stroustrup agregan perspectivas importantes:

Bjarne Stroustrup’s C++ Style and Technique FAQ

http://www.stroustrup.com/bs_faq2.html

http://www.research.att.com/~bs/bs_faq2.html

Las prácticas básicas son esenciales. Steve McConnell, ex-programador de Microsoft, tiene buen material al respecto:

Code Complete: A Practical Handbook of Software Construction

http://www.stevemcconnell.com/cc.htm

Rapid Development: Taming Wild Software Schedules

http://www.stevemcconnell.com/rd.htm

La técnica de factorización representa una excelente forma para mantener un diseño estable y flexible:

Refactoring

http://www.refactoring.com

VI. Control empírico del proceso de diseño

Un método de diseño es intrínsecamente iterativo e incremental. Se adhiere a un proceso ‘gestalt’; es decir, no puedes terminar de diseñar software si primero no lo programas, y al mismo tiempo no puedes programar software si primero no lo diseñas.

Existen métodos sistemáticos de diseño y programación, Martin Fowler habla acerca de algunos métodos actuales:

The New Methodology

http://martinfowler.com/articles/newMethodology.html

Continuous Integration (no daily build)

http://martinfowler.com/articles/continuousIntegration.html

VII. Método sistemático de diseño

Un método sistemático de programación consiste de al menos tres partes:

a. Una notación — el énfasis aquí es contar con un conjunto de conceptos de diseño que guarden coherencia y que puedan ser expresados por medio de dicha notación. Actualmente está de moda UML y es importante tener mentalmente disponibles sus conceptos para comunicar la arquitectura de software. Pero para el diseño detallado (código fuente) la notación más eficiente y efectiva sigue siendo el lenguaje de programación seleccionado.

En otras palabras, todo lo que se puede expresar en un diagrama de clases en UML se puede expresar en el código fuente; y mientras las herramientas de generación de código carezcan del nivel de abstracción suficiente para eliminar la necesidad de modificar el código generado, el diseño detallado seguirá siendo el código fuente en sintaxis del lenguaje de programación.

En el futuro, seguramente habrá las herramientas para expresar todos los aspectos del diseño detallado en una notación como UML, y entonces eso será nuestra nueva forma de código fuente.

b. Un proceso — actividades, roles y artefactos. Los mejores procesos son los que incluyen un ciclo cerrado de retro-alimentación que se ajusta a la naturaleza ‘gestalt’ del software.

Los artículos en el siguiente sitio tienen información relevante acerca de los procesos que varios programadores profesionales han sintetizado:

http://www.extremeprogramming.org

http://www.agilealliance.org

¿Qué es «Software craftsmanship»?

https://blogs.msdn.microsoft.com/destreza/2017/03/19/que-es-software-craftsmanship/

El potencial de los métodos ágiles de diseño está en la esencia del desarrollo cooperativo:

-Control empírico del proceso de desarrollo

-Comportamiento emergente o adaptativo

-Auto-organización

c. Herramientas — que soporten el conjunto de conceptos disponibles en la notación.

En la práctica, lo más eficiente y efectivo, si el objetivo es obtener software ejecutable, es usar las herramientas más simples que ayuden con la comunicación entre las personas en el equipo de desarrollo y entre los individuos y la computadora.

En otras palabras, una simple hoja de papel y lápiz, o un pizarrón, son más efectivas que costosas herramientas CASE. No menos importante, el compilador es la mejor herramienta para verificar el aspecto estático de tu diseño detallado, el compilador hará un análisis preciso de tus decisiones de diseño y te dirá invariablemente toda inconsistencia con su sistema de tipos.

Además, para verificar los aspectos dinámicos de tu diseño, un contexto de pruebas unitarias (unit-testing framework) te ayudará a obtener la retroalimentación para evolucionar tu diseño de forma coherente y concreta, satisfaciendo los aspectos de la Vista de Casos de Uso de tu arquitectura.

Kent Beck y Erich Gamma exponen el diseño de un contexto de pruebas aquí:

JUnit Cookbook

http://junit.sourceforge.net/doc/cookbook/cookbook.htm

JUnit A Cook’s Tour

http://junit.sourceforge.net/doc/cookstour/cookstour.htm

Como dice Martin Fowler: «Never in the field of software development was so much owed by so many to so few lines of code».

http://www.junit.org

Contextos de pruebas para varios lenguajes de programación están disponibles aquí (incluyendo la versión en C++Builder que hice del CppUnit de Michael Feathers):

http://www.xprogramming.com/software.htm

En general, el material en este sitio provee buen material para el diseño y desarrollo de software:

http://butunclebob.com/

http://www.objectmentor.com/resources/articles

Los mejores métodos sistemáticos de diseño y programación actuales se derivan del trabajo de las siguientes luminarias:

Profesor Edsger Wybe Dijkstra

http://www.cs.utexas.edu/users/EWD/

Kristen Nygaard

http://www.mn.uio.no/ifi/english/about/kristen-nygaard/

http://www.ifi.uio.no/~kristen/

Ole-Johan Dahl

http://www.mn.uio.no/ifi/english/about/ole-johan-dahl/

http://www.ifi.uio.no/%7Eolejohan/

Alan Turing

http://www.turing.org.uk/turing/

Niklaus Wirth

https://www.inf.ethz.ch/personal/wirth/

http://www.cs.inf.ethz.ch/~wirth/

Donald E. Knuth

http://www-cs-faculty.stanford.edu/~knuth/

Bjarne Stroustrup

http://www.stroustrup.com/

http://www.research.att.com/~bs/homepage.html

Barbara Liskov

http://www.pmg.csail.mit.edu/~liskov/

http://www.objectmentor.com/resources/articles/lsp.pdf

David Lorge Parnas

https://www.computer.org/web/awards/mills-david-parnas

http://www.crl.mcmaster.ca/SERG/parnas.homepg

Tom DeMarco

http://www.systemsguild.com/tdm.htm

http://www.atlsysguild.com/GuildSite/TDM/Tom_DeMarco.html

Gerald M. Weinberg

http://www.geraldmweinberg.com

Larry Constantine

http://wiki.c2.com/?LarryConstantine

http://www.foruse.com/

Edward Yourdon

https://yourdon.com/

Meilir Page-Jones

http://www.construx.com/Employees/Meilir_Page-Jones/

Grady Booch

http://researcher.watson.ibm.com/researcher/view.php?person=us-gbooch

James Rumbaugh

https://en.wikipedia.org/wiki/James_Rumbaugh

Ivar Jacobson

https://www.ivarjacobson.com/

Bertrand Meyer

http://www.eiffel.com

VIII. Dimensiones en desarrollo de software

Los factores para la calidad del diseño y desarrollo de software se pueden agrupar en cuatro dimensiones:

a. Personas – el aspecto más importante y que aporta en general los factores determinantes para la calidad del software

El trabajo de Tom DeMarco y Tim Lister habla de esto desde hace ya muchos años

http://www.systemsguild.com/tdm.htm

First-Order Components in Software Development (People-oriented programming, non-linear response) de Alistair Cockburn

http://alistair.cockburn.us/Characterizing+people+as+non-linear,+first-order+components+in+software+development

http://crystalmethodologies.org/articles/panlc/peopleasnonlinearcomponents.html

Las personas en el diseño y programación orientada a objetos, de un servidor:

https://sg.com.mx/content/view/338

http://www.rosenblueth.mx/InterFAR/Vol1Num3/doc/Vol1Num3-48.htm

b. Proceso – las secciones VI y VII arriba.

c. Arquitectura de Producto – las secciones II, III, IV y V arriba.

Si un producto de software es correcto y robusto, es porque su código fuente tiene una adecuada administración de dependencias internas y conserva un adecuado sentido de estética y orden entre sus componentes; si un producto de software es modular y extensible es porque su código fuente tiene esas propiedades.

De ninguna otra manera es posible conseguir la calidad externa del software si no se atiende desde el principio la calidad interna. De esto trata el siguiente artículo de Bertrand Meyer:

Factores de la calidad del software

http://www.angelfire.com/dc/marcodorantes/Docs/CalidadDelSoftware.doc

d. Tecnología – aquí va todo el conocimiento específico de una plataforma de cómputo

IX. Pensamiento sistémico

Patrones y la teoría general de sistemas para el futuro (que ya paso) – existe material importante y un cuerpo de conocimiento fundamental que, sin importar lo que diga la mercadotecnia, es indispensable dominar para ser relevante en desarrollo de software ahora y siempre. Se trata de los patrones o mecanismos análogos de la teoría general de sistemas.

Comúnmente se escucha de patrones de diseño; sin embargo, esos pertenecen a una categoría, pero los hay por todos lados: patrones de proceso, patrones organizacionales, patrones arquitectónicos, patrones de implementación (idioms), patrones de análisis. Esto equivale a lo que la teoría general de sistemas estudia como situaciones análogas en relación a los procesos de pensamiento en los seres humanos.

Las herramientas de pensamiento para diseño moderno de software están disponibles y serán las bases para el software que estaremos usando en el cual se utilizan múltiples paradigmas para su diseño.

Algunas referencias al respecto:

•Patrones

Pattern Languages of Programs

http://hillside.net/conferences

http://jerry.cs.uiuc.edu/~plop/

Euro-Plop

http://www.europlop.net/

http://www.argo.be/europlop/Papers/Final/

Portland Pattern Repository

http://c2.com/cgi/wiki?PortlandPatternRepository

Patrones organizacionales de James Coplien

https://amzn.com/0131467409

http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?CoplienOrganizationPatterns

•Diseño multi-paradigma

Generative Programming

https://amzn.com/0201309777

http://www.generative-programming.org/

http://www.prakinf.tu-ilmenau.de/~czarn/generate/engl.html

Aspect-Oriented Programming

http://www2.parc.com/csl/groups/sda/

http://aosd.net

Intentional Programming

http://www.intentionalsoftware.com

http://www.c2.com/cgi/wiki?IntentionalProgramming

Generic Programming

http://www.lafstern.org/matt/

•Acerca de la teoría general de sistemas

Cybernetics and Systems Theory

http://pespmc1.vub.ac.be/CYBSYSTH.html

«Este no es el final, ni siquiera es el comienzo del final; tal vez, tan sólo es el final del comienzo» —Winston Churchill


Comments (0)

Skip to main content