Sistemas IV

De Computacion

La materia de sistemas IV es el último escalón en lo que a programación y desarrollo de sistemas se refiere, en este curso se van a analizar conceptos de programación y arquitectura avanzados; pensando siempre en que debemos ser entes que propongamos soluciones nuevas y ágiles a viejos problemas. Hoy en día se suele y debe realizarse un análisis, diseño e implementación orientado a objetos, a no ser que la propia aplicación o el campo en el que nos movemos requieran otro método de trabajo. Durante el análisis se observa el dominio del problema para construir un modelo del mundo real utilizando objetos. El diseño consiste en el refinamiento de los modelos de análisis para crear especificaciones adicionales que enriquecen el modelo de análisis con detalles próximos a la implementación. Una solución lógica, de forma que se cumplan los requerimientos (asignación de responsabilidades, interacciones entre objetos, etc.) La implementación la deberemos realizar en un lenguaje orientado a objetos, durante la cual codificaremos el diseño obtenido en las fases de análisis y diseño. (Lenguajes OO: Java, C++, Delphi, C#, entre otros) Este modo de programación se basa en objetos, y supone que éstos son las entidades más estables del sistema, de esta forma:

  • Un diseño basado en estos objetos del dominio será más resistente al cambio.
  • Fusiona los modelos de proceso y de datos.
  • Reduce el vacío entre el software y los modelos de negocio.

A pesar de todas estas divisiones sigue habiendo interacciones debidas al uso inadecuado de la orientación a objetos, una muy común es el mal empleo de la encapsulación.

Otro de los problemas fundamentales es el vacío existente entre el análisis, diseño e implementación, que hace que el programador tenga que tomar decisiones de diseño, o se produzca sobrespecificación. Para solventar estos problemas se produce un nuevo enfoque: el diseño con patrones. La idea nace del arquitecto Christopher Alexander, que aplica el concepto a la construcción urbanística.

El concepto es construir usando soluciones que en el pasado han funcionado bien, pero no por mera casualidad sino mas bien por la experiencia que ha generado a lo largo del tiempo.

Tabla de contenidos


Objetivos Generales

  • Proveer al estudiante las herramientas necesarias para que pueda construir aplicaciones empresariales distribuidas y que apliquen conceptos de arquitectura avanzados.

Objetivos Especificos

  • Recordar de dónde proviene el desarrollo de software, la arquitectura y cuál es su perspectiva a futuro.
  • Conocer las características y lineamientos fundamentales que rigen en la arquitectura de software orientada a objetos.
  • Entender la base teórica de los patrones de diseño y su aporte a la arquitectura orientada a objetos.
  • Aplicar de manera práctica los conceptos sobre patrones de diseño.
  • Hacer un análisis sobre el futuro de la programación y arquitectura orientada a objetos.

Bibliografía

Texto Básico:

GAMMA, E.; HELM, R.; JONSON, R.; VLISSIDES, J. Patrones de Diseño. Elementos de Software Orientado a Objetos Reutilizable, Pearson Eduaction, S.A., Madrid 2003, 384 p.

A veces se da el caso de libros que, por la especial contribución que realizan en un campo determinado, se convierten en clásicos apenas han sido publicados. Este libro constituye uno de esos casos excepcionales. En efecto, a pesar de los pocos años transcurridos desde la publicación original en inglés, ha revolucionado el campo de la arquitectura del software, llevando la tecnología de la orientación a objetos a un estado mas avanzado de su evolución.


Desarrollo del Aprendizaje

Capitulo 1: PROGRAMACIÓN ORIENTADA A OBJETOS



Datos Generales:

Referencia base

[1] Capítulo de Anexo en la Guía [2] No Silver Bullet. Disponible en: http://www-inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.htm

Anexo

Anexo 1. Programación Orientada A Objetos Anexo 2. No Silver Bullet

Referencias

Adicionales||

Horas de estudio empleadas para el desarrollo del contenido 8 horas

Propositos:


El propósito de este capítulo es introducir al estudiante en los ámbitos de la programación orientada a objetos como elemento clave en las organizaciones para alcanzar ventajas competitivas.

Conceptos Claves:


  • Historia :

Son varios los lenguajes que han contribuido a la evolución de los lenguajes orientados a objetos de hoy: LISP en la década de los 50, Simula en los 60 y mas tarde Pascal, C, Modula y Ada. Si bien, estos lenguajes no incluyen mecanismos para la programación orientada a objetos, sus características sirvieron de base para la construcción de estos mecanismos; por ejemplo, Simula contribuye con el concepto de clase. En la década de los 70, nace SmallTalk como un lenguaje orientado a objetos puro con lo que queda introducido definitivamente este tipo de programación. En los años siguientes los avances experimentados en la programación orientada a objetos fueron pocos. Es en la década de los 80 cuando los avances son mayores, debido fundamentalmente a la disponibilidad de extensiones orientadas a objetos en dos de los lenguajes más populares, C y Pascal. Esto da lugar a la aparición de los lenguajes orientados a objetos híbridos, entre los que se destacan C++ y Pascal orientado a objetos. Estos lenguajes tienen una característica muy importante y es que guardan la compatibilidad con sus antecesores.

Imagen:Perspectiva_histórica_del_desarrollo_de_software.JPG


Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
En busca de la bala de plata Perspectiva de la programación y su evolución Leer el artículo: “NoSilver Bullet”,se lo puede encontrar en:

http://www-inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.htm

Historia Historia del desarrollo de software
Conceptos fundamentales Conceptos base sobre la programación orientada a objetos Lectura: Texto base, Apéndice B – Guía de la Notación págs. 333 - 337


Capitulo 2:CONSTRUCCIÓN DE APLICACIONES EN CAPAS



Datos Generales:

Referencia baseConstrucción De Aplicaciones En Capas
AnexoAnexo 3. Construcción de aplicaciones en capas
Referencias Adicionales
Horas de estudio empleadas para el desarrollo del contenido 6 horas

Propositos:


La construcción de aplicaciones n-tier (n-capas) distribuidas ha emergido como la arquitectura predominante para la construcción de aplicaciones multiplataforma en la mayor parte de las empresas. En el presenta capítulo se hace una revisión de los tipos de arquitecturas para el desarrollo de aplicaciones en capas.

Conceptos Claves:


  • Características de las aplicaciones construidas en capas

Las aplicaciones que se construyen con una arquitectura multicapa tienen entre otras las siguientes características:

  • Acceso a bases de datos (BD)
o Normalmente con BD relacionales
  • Transaccionales
o Propiedades ACID (Atomicity-Consistency-Isolation-Durability)
  • Operaciones atómicas (Atomicity) son operaciones que se completan en su totalidad o no se completan en absoluto. Así, en el ejemplo anterior de la transferencia tanto el crédito como el débito deben haber sido exitosos para que el estado de transformación sea exitoso (para que haga efectos), de otro modo el estado de la transformación falla, y el sistema es regresado a su último estado conocido.

  • Transformaciones consistentes (Consistency) preservan la integridad interna de los recursos involucrados. Por ejemplo, el borrar registros de una tabla primaria viola la integridad referencial de la base de datos si hay registros relacionados que concuerden.

  • Transformaciones aisladas (Isolation) parecen ocurrir serialmente, una detrás de otra, creando la ilusión de que ninguna transformación está siendo ejecutada al mismo tiempo.

  • La durabilidad (Durability) se refiere a la habilidad para almacenar los resultados de una transformación de estado, usualmente en un disco, de tal modo que los resultados de una transformación puedan ser recuperados en caso de una falla del sistema.

  • Escalables
o Deberían poder soportar más carga de trabajo sin necesidad de modificar el software (sólo añadir más máquinas).
  • Disponibilidad
o Idealmente no deben dejar de prestar servicio.
  • Seguras
o No todos los usuarios pueden acceder a la misma funcionalidad.
  • Integración
o Es preciso integrar aplicaciones construidas con distintas tecnologías.
  • Tipo de interfaz
o De entorno de ventanas (clientes desktop): normalmente sólo tiene sentido en intranets.
o Web: En Internet y en intranets.
  • Separación clara entre la interfaz gráfica y la Capa de componentes
o Capa de componentes: encapsulan la lógica de negocio.
o Ejemplo => aplicación bancaria.

o Capa de componentes: conjunto de clases que nos permiten: crear cuentas, destruirlas, encontrarlas por distintos criterios, hacer transferencias bancarias, etc.

o La capa de componentes debería ser reusable con distintas interfaces gráficas
o En el ejemplo de la aplicación bancaria podría haber dos clientes: uno Web y otro desktop.

Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
Generalidades Perspectiva de la arquitectura de aplicaciones.
Características Describe las características de las aplicaciones en capas.
Aplicaciones de una capa Conceptos fundamentales de la construcción de aplicaciones en una capa.
Aplicaciones de dos capas Conceptos fundamentales de la construcción de aplicaciones en dos capas.
Aplicaciones de tres capas Conceptos fundamentales de la construcción de aplicaciones en tres capas.
Aplicaciones de n capas Conceptos fundamentales de la construcción de aplicaciones en n capas. Discutir sobre la experiencia de aplicaciones y su optimización usando patrones de diseño.


Capitulo 3: PATRONES DE DISEÑO

Datos Generales:

Referencia basePatrones de Diseño
AnexoAnexo 4. Patrones de Diseño
Referencias Adicionales
Horas de estudio empleadas para el desarrollo del contenido 20 horas

Propositos:


El propósito del presente capítulo, es dar una introducción hacia el concepto de patrones de diseño en el entorno de desarrollo de software.

Conceptos Claves:


  • Historia

Los patrones como elemento de la reutilización, comenzaron a utilizarse en la arquitectura con el objetivo de reutilizar diseños que se habían aplicado en otras construcciones y que se catalogaron como completos.

  • Christopher Alexander

    fue el primero en intentar crear un formato específico para patrones en la arquitectura. Alexander argumenta que los métodos comunes aplicados en la arquitectura dan lugar a productos que no satisfacen las demandas y requerimientos de los usuarios y son ineficientes a la hora de conseguir el propósito de todo diseño y esfuerzo de la ingeniería: mejorar la condición humana.

Christopher Alexander da la siguiente definición de patrón:

“Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, para describir después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada más de un millón de veces sin hacerlo ni siquiera dos veces de la misma forma”.

Si nos fijamos en las construcciones de una determinada zona rural observaremos que todas ellas poseen apariencias parejas (tejados de pizarra con gran pendiente, etc.), pese a que los requisitos personales por fuerza han debido ser distintos. De alguna manera la esencia del diseño se ha copiado de una construcción a otra, y a esta esencia se pliegan de forma natural los diversos requisitos. Se puede ver que aquí existe un patrón que soluciona de forma simple y efectiva los problemas de construcción en tal zona.

En definitiva se puede definir un patrón como “una solución a un problema en un determinado contexto”.

El término patrón se utiliza inicialmente en el campo de la arquitectura, por Christopher Alexander, a finales de los 70’s. Este conocimiento es transportado al ámbito del desarrollo de software orientado a objetos y se aplica al diseño. De allí es extrapolado al desarrollo en general y a las demás etapas.

En 1987, Ward Cunningham y Kent Beck trabajaron con Smaltalk y diseñaron interfaces de usuario. Decidieron, para ello, utilizar alguna de las ideas de Alexander para desarrollar un lenguaje pequeño de patrones para servir de guía a los programadores de Smaltalk. Así dieron lugar al libro “Using Pattern Languajes for Object-Oriented Programs”.

Poco después, Jim Coplien comenzó a realizar un catálogo de idioms (que son un tipo de patrones) en C++ y publica su libro “Advanced C++ Programming Styles and Idioms” en 1991.

Desde 1990 a 1994, Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides (el grupo de los cuatro) realizaron un primer catálogo de patrones de diseño.

Posteriormente hubo diferentes discusiones a cerca de los patrones en las que participaron notables personalidades de los patrones.

Poco después de Abril de 1994 el libro “Design Patterns: Elements of Reusable Object- Oriented Software” (Gang of Four, [GoF]) es publicado, el mismo que es el libro base de nuestro curso.

Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
Introducción Una introducción a la teoría de patrones de diseño Libro base: Patrones de Diseño:
  • Prólogo pág. XIII
  • Introducción Págs. 1 - 3
Historia Una breve descripción de la historia de los Patrones de Diseño Libro base: Patrones de Diseño:
  • 6.2 Una breve historia pág. 325
Patrones de Software La aplicación del concepto en el entorno de desarrollo de software
Características Características básicas de los patrones de diseño
Elementos Elementos esenciales de los patrones de diseño Libro base: Patrones de Diseño:
  • 1.1 ¿Qué es un patrón de diseño? págs. 3 - 4
Descripción El uso de una plantilla para la descripción de los patrones de diseño Libro base: Patrones de Diseño:
  • 1.3 Descripción de los patrones de diseño págs. 6 - 7
Clasificación La clasificación de los patrones de diseño Libro base: Patrones de Diseño:
  • 1.5 Organización del catálogo págs. 9 - 10
Patrones y Frameworks Comparación de los patrones de diseño con otras abstracciones en la industria del desarrollo de software Libro base: Patrones de Diseño:
  • 1.6 Cómo resuelven los patrones los problemas de diseño págs. 10 - 25


Capitulo 4 : Patrones de Creación



Datos Generales:

Texto Base GAMMA, E.; HELM, R.; JONSON, R.; VLISSIDES, J. Patrones de Diseño. Elementos de Software Orientado a Objetos Reutilizable, Pearson Eduaction, S.A., Madrid 2003, 384 p.
Anexo
Referencias Adicionales Los ejemplos de la guía son tomados del sitio:

http://www.dofactory.com/Patterns/Patterns.aspx, han sido copiados “tal cual”, están en inglés y el lenguaje de programación es C#.

Páginas 79 - 127
Horas de estudio empleadas para el desarrollo del contenido 8 horas

Propositos:


El propósito de este capítulo es introducir en el conocimiento de los patrones de creación como base para el conocimiento de los patrones de diseño

Conceptos Claves:


  • Patrones de Creación

Los patrones de creación proporcionan ayuda a la hora de crear objetos, principalmente cuando esta creación requiere tomar decisiones. Esta toma de decisiones puede ser dinámica. Estos patrones ayudan a estructurar y encapsular estas decisiones. En algunas ocasiones existe más de un patrón que se puede aplicar a la misma situación. En otras ocasiones se pueden combinar múltiples patrones convenientemente. Un patrón de creación asociado a clases usa la herencia para variar la clase que se instancia, mientras que un patrón de creación asociado a objetos delegará la instanciación a otro objeto.

Hay dos formas de clasificar los patrones de creación basándose en las clases de objetos que se crean. Una es clasificar las clases que crean los objetos (Factory Method), otra forma está relacionada con la composición de objetos; definir un objeto que es responsable de conocer las clases de los objetos producto, en esta característica se apoyan los patrones Abstract Factory, Builder o Prototype.

En muchas ocasiones los patrones de creación compiten en su función. Por ejemplo, hay casos donde Protoype y Abstract Factory puede utilizarse indistintamente. En otras ocasiones Builder puede usar a los otros patrones para implementar los componentes que construye.

Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
Abstract Factory Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Builder Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Factory Method Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Prototye Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Singleton Revisión de la teoría sobre el mencionado patrón de diseño Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Discusión sobre los patrones de creación Discusión sobre los patrones de creación Lectura del Texto Base


Capitulo 5 : Patrones Estructurales



Datos Generales:

Texto BaseGAMMA, E.; HELM, R.; JONSON, R.; VLISSIDES, J. Patrones de Diseño. Elementos de Software Orientado a Objetos Reutilizable, Pearson Eduaction, S.A., Madrid 2003, 384 p.
Anexo
Referencias Adicionales Los ejemplos de la guía son tomados del sitio:

http://www.dofactory.com/Patterns/Patterns.aspx, han sido copiados “tal cual”, están en inglés y el lenguaje de programación es C#.

Páginas131 - 201
Horas de estudio empleadas para el desarrollo del contenido12 horas

Propositos:


El propósito de este capítulo es introducir en el conocimiento de los patrones estructurales como base para el conocimiento de los patrones de diseño.

Conceptos Claves:


Patrones Estructurales

Los patrones estructurales están relacionados con cómo las clases y los objetos se combinan para dar lugar a estructuras más complejas. Puede hacerse aquí la misma distinción que hacíamos en los patrones de creación y hablar de patrones estructurales asociados a clases (Adapter) y asociados a objetos (Bridge, Composite, Decorator, Facade, Flyweight, Proxy), los primeros utilizarán la herencia, los segundos la composición.

Los patrones estructurales asociados con objetos describen formas de componer los objetos para conseguir nueva funcionalidad. La flexibilidad de la composición de objetos viene de la posibilidad de cambiar la composición en tiempo de ejecución, lo que es imposible con la composición estática de clases.


Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
Adapter Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Composite Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Decorator Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Facade Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Flyweight Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Proxy Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Discusión sobre los patrones estructurales Discusión sobre los patrones estructurales. Lectura del Texto Base


Capitulo 6 :Patrones de Comportamiento



Datos Generales:

Texto BaseGAMMA, E.; HELM, R.; JONSON, R.; VLISSIDES, J. Patrones de Diseño. Elementos de Software Orientado a Objetos Reutilizable, Pearson Eduaction, S.A., Madrid 2003, 384 p.
Anexo
Referencias Adicionales Los ejemplos de la guía son tomados del sitio:

http://www.dofactory.com/Patterns/Patterns.aspx, han sido copiados “tal cual”, están en inglés y el lenguaje de programación es C#.

Páginas205 - 317
Horas de estudio empleadas para el desarrollo del contenido 10 horas

Propositos:


El propósito de este capítulo es introducir en el conocimiento de los patrones de comportamiento como base para el conocimiento de los patrones de diseño.

Conceptos Claves:


  • Patrones de Comportamiento

    Estos patrones de diseño están relacionados con algoritmos y asignación de responsabilidades a los objetos. Los patrones de comportamiento describen no solamente patrones de objetos o clases sino también patrones de comunicación entre ellos. Nuevamente se pueden clasificar en función de que trabajen con clases (Template Method, Interpreter) u objetos (Chain of Responsability, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor).

La variación de la encapsulación es la base de muchos patrones de comportamiento. Cuando un aspecto de un programa cambia frecuentemente, estos patrones definen un objeto que encapsula dicho aspecto. Los patrones definen una clase abstracta que describe la encapsulación del objeto.

Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
Chain of Responsability Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Command Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Interpreter Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Iterator Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Mediator Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Memento Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Observer Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
State Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Strategy Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Template Method Revisión de la teoría sobre el mencionado patrón de diseño. Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Visitor Revisión de la teoría sobre el mencionado patrón de diseño Se recomienda codificar todos los ejemplos del sitio http://www.dofactory.com/Patterns/Patterns.aspx y compilarlos; están escritos en C#.
Discusión sobre los patrones de Comportamiento Discusión sobre los patrones de Comportamiento. Lectura del Texto Base


Capitulo 7 : Conclusión



Datos Generales:

<center>

Texto BaseGAMMA, E.; HELM, R.; JONSON, R.; VLISSIDES, J. Patrones de Diseño. Elementos de Software Orientado a Objetos Reutilizable, Pearson Eduaction, S.A., Madrid 2003, 384 p.
Anexo
Referencias Adicionales Los ejemplos de la guía son tomados del sitio:

http://www.dofactory.com/Patterns/Patterns.aspx, han sido copiados “tal cual”, están en inglés y el lenguaje de programación es C#.

Páginas322 - 328
Horas de estudio empleadas para el desarrollo del contenido2 horas

Propositos:

El propósito de este capítulo es brindar un enfoque a futuro acerca de la utilización de Patrones de Diseño en el desarrollo de aplicaciones empresariales.

Conceptos Claves:


  • Conclusión :

    La gran popularidad que han ido adquiriendo los patrones hacen que la comunidad de software los utilice y los soporte comúnmente.

Varias notaciones usadas por las Tecnologías Orientadas a Objetos han añadido soporte para el modelado y representación de patrones de diseño. Muchas herramientas de desarrollo de software han añadido un soporte similar. Algunos proyectos de investigación están intentando codificar patrones de diseño con el propósito de generar código fuente. Algunas librerías comerciales de software proporcionan implementación de algunos patrones de diseño.. Se piensa que en poco tiempo los lenguajes de programación introducirán sintaxis para representar patrones como unidades de construcción de software.

(Java utiliza unos pocos patrones en sus librerías estándar, Microsoft ha empaquetado los principales en librerías de uso libre, la Enterprise Library).

Hay una especulación a cerca de sí los patrones sustituirán algún día a los programadores. Esta misma especulación ya ha aparecido en algunas ocasiones con la introducción de nuevas tecnologías. Los lenguajes y las herramientas que se usan para solucionar problemas software evolucionarán, pero se seguirá necesitando desarrolladores con la misma evolución.

Aunque la habilidad de codificar patrones como componentes de software pueda llegar a ser importante, más importante será el conocimiento de cómo y cuando aplicar y combinar patrones, en conjunción con la habilidad de usar un vocabulario de nombres de patrones para comunicarse con otros desarrolladores.


Esquema de Estudio:


A continuación se detallan los temas que se deben desarrollar, una descripción general del mismo, y un conjunto de actividades que se recomienda sean desarrolladas para una mejor asimilación de los conceptos. Se han dispuesto las tres columnas de la derecha para llevar un control personal del tiempo de dedicación a cada tema, marcar las actividades que cada estudiante estima que necesita tutoría y realizar anotaciones personales.

Tema a revisar Descripción del Contenido a revisar Actividades Recomendadas Planificación Personal del estudio (fecha) ¿Requiero Tutorial? Anotaciones
¿Qué esperar de los patrones de diseño? Perspectiva de los patrones de diseño a futuro. Lectura del Texto Base
Una breve historia Origen de los patrones de diseño. Lectura del Texto Base
La comunidad de patrones La generalización de los patrones de diseño. Lectura del Texto Base
Una invitación Una invitación para seguir aprendiendo. Lectura del Texto Base
Una reflexión a modo de despedida Palabras de ánimo para el estudio de los patrones de diseño. Lectura del Texto Base


ANEXOS



Anexo 1


Programación Orientada A Objetos

En busca de la bala de plata

Sobre los programas que prometen “revolucionar” la industria del software, y que aparecen cada pocos años para ser rápidamente olvidados nada mejor que leer el artículo clásico de 1987 “No Silver Bullet”. Su planteamiento es el siguiente: La programación se compone de dos partes, las partes “intrínsecas” al trabajo de programación (pensar en el problema, resolver las ambigüedades, entender los estándares, “pensar” al fin y al cabo) y las partes que podríamos considerar “accidentales” (expresar la idea en el lenguaje de programación, el propio acto de teclear, etc.).

Cualquier sistema que aparezca solo puede tratar de acortar las partes “accidentales”. Alguien puede crear un lenguaje de programación más fácil para exponer las ideas (o que me permita expresarlas con dibujos, como el UML), un reconocedor de voz que me evite escribir en el teclado. goritmo concreto que el ordenador debe seguir. <p align='justify'> Son sistemas experimentales como la programación genética o sistemas conocidos desde hace años como la programación lógica, la programación funcional, los sistemas de aprendizaje por reglas o las redes neuronales. Algunos de estos sistemas han tenido y tienen muy buenos resultados en áreas concretas aunque hasta ahora no se ha sabido exportar su éxito al software en general. Añadir más gente a un proyecto porque dicho proyecto tiene un retraso, no sólo no ayuda, sino que hace que el proyecto se retrase aún más. Y esto se debe al mito de que si un programa se puede desarrollar por 100 personas en 6 meses, 200 personas lo harán en 3 meses. Totalmente falso en el mundo del software. Hay que jerarquizar los recursos humanos del proyecto teniendo un arquitecto global y luego grupos que se dividen en subgrupos y así sucesivamente hasta tener grupos de programadores de unas 6-10 personas que funcionan como un cirujano en un quirófano: cada uno tiene su papel perfectamente definido y están al servicio del cirujano, una versión inferior del arquitecto global. Es importante la figura del arquitecto porque le da consistencia al producto final, y esto es vital para el éxito del proyecto y que ejerce una gran influencia en cosas tan importantes como la facilidad de uso y la mantenibilidad del producto final.

Podríamos decir que “una mujer hace un niño en nueve meses, pero nueve mujeres no hacen un niño en un mes”

Se puede comparar el proceso de desarrollo de un producto software con un hombre lobo. Es algo monstruosamente feo y peligroso en el sentido de que es muy fácil que fracase. Lo bueno de los hombres lobo es que una bala de plata es todo lo que se necesita para acabar con el problema. En el software, no existe la bala de plata, el remedio para el problema, el milagro que todos esperamos... Como se comentó al inicio de esta unidad, existen dos tipos de problemas con el software, los esenciales y los accidentales. Los esenciales son problemas intrínsecos de desarrollar software y no los podemos evitar (complejidad, conformidad, facilidad de cambio, invisibilidad...).

Los accidentales básicamente residen en las herramientas y los métodos que utilizamos y aquí es donde podemos mejorar la situación actual.

Orientación a objetos, programación de alto nivel, herramientas colaborativas y documentación semiautomática son algunas ideas que Frederick P. Brooks, Jr., allá por el año de 1987, predijo que podrían ayudarnos y efectivamente así ha sido, aunque no precisamente un orden de magnitud, como se esperaba de ellas. Son varios los lenguajes que han contribuido a la evolución de los lenguajes orientados a objetos de hoy: LISP en la década de los 50, Simula en los 60 y mas tarde Pascal, C, Modula y Ada. Si bien, estos lenguajes no incluyen mecanismos para la programación orientada a objetos, sus características sirvieron de base para la construcción de estos mecanismos; por ejemplo, Simula contribuye con el concepto de clase. En la década de los 70, nace SmallTalk como un lenguaje orientado a objetos puro con lo que queda introducido definitivamente este tipo de programación. En los años siguientes los avances experimentados en la programación orientada a objetos fueron pocos. Es en la década de los 80 cuando los avances son mayores, debido fundamentalmente a la disponibilidad de extensiones orientadas a objetos en dos de los lenguajes más populares, C y Pascal. Esto da lugar a la aparición de los lenguajes orientados a objetos híbridos, entre los que se destacan C++ y Pascal orientado a objetos. Estos lenguajes tienen una característica muy importante y es que guardan la compatibilidad con sus antecesores.

Imagen:Anexo_1.JPG

Desarrollo de los lenguajes de programación

El Lenguaje C

El lenguaje C nació en los laboratorios Bell de AT&T y ha sido estrechamente asociado con el sistema operativo UNIX, ya que su desarrollo se realizó en este sistema y debido a que tanto UNIX como el propio compilador C y casi la totalidad de los programas y herramientas de UNIX, fueron escritos en C. Su eficiencia y claridad han hecho que el lenguaje ensamblador apenas haya sido utilizado en UNIX. Este lenguaje está inspirado en el lenguaje B escrito por Ken Thompson en 1970 con intención de recodificar el UNIX, que en la fase de arranque estaba escrito en ensamblador, en vista a su transportabilidad a otras máquinas. B era un lenguaje evolucionado e independiente de la máquina, inspirado en el lenguaje BCPL concebido por Martin Richard en 1967. En 1972, Dennis Ritchie, toma el relevo y modifica el lenguaje B, creando el lenguaje C y rescribiendo el UNIX en dicho lenguaje. La novedad que proporcionó el lenguaje C sobre el B fue el diseño de tipos y estructuras de datos. Una de las peculiaridades de C es su riqueza de operadores. Puede decirse que prácticamente dispone de un operador para cada una de las posibles operaciones en código máquina.

Imagen:Anexo_1_1.JPG

Dependencia

Este lenguaje ha evolucionado paralelamente a UNIX. Así, en 1980 se añaden al lenguaje C, características como las clases (Tomado de Simula67), chequeo y conversión de los tipos de argumentos de función, etc.; el resultado fue el lenguaje denominado “C con Clases”. En 1983/84, “C con Clases” fue rediseñado, extendido y nuevamente implementado. El resultado se denomino “Lenguaje C++”. Después de algún otro refinamiento más, C++ queda disponible en 1985.

El nombre C++ se debe a Rick Mascitti, significando “el carácter evolutivo de las transformaciones de C” (‘++’ es el operador de incremento de C).

El Lenguaje Java

Java fue diseñado por James Gosling, de Sun Microsystems, en 1990, como software para dispositivos electrónicos de consumo. Curiosamente, todo este lenguaje fue diseñado antes de que diese comienzo la era World Wide Web, puesto que fue diseñado para dispositivos electrónicos como calculadoras, microondas, y la televisión interactiva entre otros. En los primeros años de la década de los noventa, Sun Microsystems decidió intentar introducirse en el mercado de la electrónica de consumo y desarrollar programas para pequeños dispositivos electrónicos. Tras unos comienzos dudosos, Sun decidió crear una filial, denominada FirstPerson Inc., para dar margen de maniobra al equipo responsable del proyecto.

Inicialmente Java se llamó OAK (roble en inglés), aunque tuvo que cambiar debido a la existencia de que dicho nombre ya estaba registrado por otra empresa.

Tres de las principales razones que llevaron a crear Java son las siguientes:

  • Creciente necesidad de interfaces mucho más cómodos e intuitivos que los sistemas de ventanas que proliferaban hasta el momento.
  • Fiabilidad del código y facilidad de desarrollo. Gosling observó que muchas de las características que ofrecían C o C++ para este tipo de dispositivos aumentaban de forma alarmante el gran costo de pruebas y depuración. Por ello en los sus ratos libres creó un lenguaje de programación donde intentaba solucionar los fallos que encontraba en C++.

  • El funcionamiento de dispositivos electrónicos se controla mediante la utilización de microprocesadores de bajo precio y reducidas prestaciones, de los que existe una diversidad abrumadora. Además, se desarrollan nuevos modelos más perfeccionados y baratos cada pocas semanas y los fabricantes tratan siempre de aprovecharlos para reducir costos en las grandes producciones que realizan. Sin embargo, las diferentes familias de microprocesadores emplean un juego de instrucciones diferentes, e incluso las nuevas versiones de modelos antiguos suelen añadir o modificar instrucciones para aprovechar al máximo las nuevas posibilidades de los chips. Por este motivo, el software escrito debe ser revisado por completo antes de poder utilizarlo en otro. Naturalmente, la existencia de compiladores alivia esta labor, facilitando la utilización de C en lugar de ensamblador, pero esto no es suficiente: muchas de las diferencias básicas entre microprocesadores (direcciones concretas de memoria, tamaño y número de registros, acceso a puertos de entrada/salida) se manifiestan directamente en el código C, del que debe desarrollarse una nueva versión para cada chip que desea utilizarse.

Por todo ello, en lugar de tratar únicamente de optimizar las técnicas de desarrollo y dar por sentado la utilización de C o C++, el equipo de Gosling se planteó que tal vez estos lenguajes eran demasiado complicados como para conseguir reducir de forma apreciable la complejidad asociada a este campo.

Por este motivo, su primera propuesta fue idear un nuevo lenguaje de programación lo más sencillo posible, con el objeto de que se pudiese adaptar con facilidad a cualquier entorno de ejecución. Basándose en el conocimiento y estudio de gran cantidad de lenguajes, este grupo decidió recoger las características esenciales que debía tener un lenguaje de programación moderno y potente, pero eliminando todas aquellas funciones que no eran absolutamente imprescindibles.

Concepto:

El término de Programación Orientada a Objetos (POO) indica más una forma de diseño y una metodología de desarrollo de software que un lenguaje de programación, ya que en realidad se puede aplicar el Diseño Orientado a Objetos (DOO), a cualquier tipo de lenguaje de programación.

La POO proporciona las siguientes ventajas sobre otros lenguajes de programación:

  • Uniformidad. Ya que la representación de los objetos lleva implica tanto el análisis como el diseño y la codificación de los mismos.

  • Comprensión. Tanto los datos que componen los objetos, como los procedimientos que los manipulan, están agrupados en clases, que se corresponden con las estructuras de información que el programa trata.

  • Flexibilidad. Al tener relacionados los procedimientos que manipulan los datos con los datos a tratar, cualquier cambio que se realice sobre ellos quedará reflejado automáticamente en cualquier lugar donde estos datos aparezcan.

  • Estabilidad. Dado que permite un tratamiento diferenciado de aquellos objetos que permanecen constantes en el tiempo sobre aquellos que cambian con frecuencia permite aislar las partes del programa que permanecen inalterables en el tiempo.

  • Reusabilidad. La noción de objeto permite que programas que traten las mismas estructuras de información reutilicen las definiciones de objetos empleadas en otros programas e incluso los procedimientos que los manipulan. De esta forma, el desarrollo de un programa puede llegar a ser una simple combinación de objetos ya definidos donde estos están relacionados de una manera particular.

Uno de los puntos clave a remarcar en esta introducción es que la programación orientada a objetos no sustituye a ninguna metodología ni lenguaje de programación anterior. Todos los programas que se realizan según DOO se pueden realizar igualmente mediante programación estructurada.

Su uso en la actualidad se justifica porque el desarrollo de todas las nuevas herramientas basadas en una interface de usuario gráfico como Windows, OS/2, x-Windows, etc. Es mucho más sencillo <(p> Abstracción

Imagen:Anexo_1_2.JPG

La POO es un paradigma de programación, una forma de pensar, una disciplina, una forma de ver las cosas.

  • La abstracción es tener claro desde mi punto de vista, la realidad que mis ojos ven.
  • Versión simplificada de la realidad, de la cual obtenemos los elementos esenciales.

Un ejemplo claro de abstracción es el desarrollo de los lenguajes de programación:

  • 1950: Lenguaje de Máquina.
  • 1960: Lenguaje ensamblador.
  • 1970: Lenguaje de alto nivel.
  • 1980: Programación estructurada.
  • En adelante: POO.

Existen otras abstracciones de lenguajes:

  • Funcional
  • Lógico (lisp) lenguaje de programación con ordenadores and y or.


Encapsulamiento

Es el proceso de ocultación de los atributos de una entidad, las cuales no son esenciales para su descripción.

  • Agrupar
  • Ocultar
  • Comprimir
Abstracción Visión Externa
Encapsulamiento Visión Interna

<p align='justify'> La abstracción nos permite ver el estado externo de la entidad, es decir describe lo que vemos por afuera; en el ejemplo del auto podremos saber su color, forma, modelo.

El encapsulamiento define el estado interno de la entidad, es decir nos indica para qué sirve y el estado; en el ejemplo de un auto podremos saber cual es el uso que podemos darle, transportarnos, trabajar y su estado, en funcionamiento, dañado, nuevo.

Objeto

Es una identidad del mundo real que tiene sus propios atributos, un estado y un comportamiento.

Ej.

  • Auto
  • Reloj
  • Persona
  • Pelota
  • Silla
  • Esfero
  • Sol

En el entorno de programación, se puede decir que es un modelo de Software del mundo real.

Atributos y estados Son definidos por variables
Comportamiento Es definido por funciones o métodos

Clase

Es una estructura de Software que define a un determinado objeto. Las clases tienen un nombre, atributos y métodos.

La clase:

  • Define la Estructura y el Comportamiento.
  • Es el “Plano” del objeto.
  • Una vez que definimos una clase, podemos crear un sin número de objetos (Instancias).
  • La clase es un mecanismo de encapsulamiento de SW.
Imagen:Anexo_1_3.JPG

La clase

Los objetos son instancias de una clase; los atributos diferencian a los objetos entre sí, el auto rojo, el auto azul, el auto del año 1990, el auto marca mazda; todo ellos con “autos”.

Herencia

Es el proceso mediante el cual una clase adquiere las propiedades de otra. Permite definir nuevas clases y/o subclases a partir de
otra. La herencia por medio de la jerarquización permite gestionar de forma sencilla la abstracción.
Herencia
Una subclase puede tener nuevos atributos y métodos.
Imagen:Anexo_1_4.JPG

La clase figura y las subclases cuadrado y círculo

Polimorfismo

Es una clase general de acción que es implementada por uno o más métodos

Imagen:Anexo_1_5.JPG

Polimorfismo del método Area

CLASE Figura

int x,y;
Mover ();
Área ();

CLASE Círculo Hereda de Figura

int radio;
Área (); donde Área = pi * radio * radio

CLASE Cuadrado Hereda de Figura

int lado;
Área (); donde Área = lado * lado


Abstracción Visión simplificada de la realidad.
Objeto Modelo de software del mundo real.
Clase Estructura de software que definen los objetos.
Herencia de las clases Heredan los atributos y/o métodos de sus padres à jerarquización de clases.
Polimorfismo Interfaz à varios métodos.

Anexo 2


No Silver Bullet

Essence and Accidents of Software Engineering

Computer Magazine; April 1987

by Frederick P. Brooks, Jr.,

University of North Carolina at Chapel Hill

This article was First Published In Information Processing 1986, ISBN No. 0444-7077-3, H. J. Kugler, Ed., Elsevia Science Publishers B.V. (North-holland) IFIP 1986. Scanned from a poor-quality faxed copy by Brad Cox which is the reason for occasional OCR errors.

I (Brad Cox) have written several articles (No Silver Bullet Revisited) and a book (Superdistribution: Objects as Property on the Electronic Frontier), and founded a company (Superdistribution Inc) based on a disagreement with the main conclusion of this article.

Briefly, Brooks argues that software disappoints because it is so different from tangible goods, being made of bits not atoms, that the solutions that make tangible goods meet our expectations cannot possibly apply. This assumption is deeply buried and only evident in the fact that Brooks neglected to even mention it as a solution (e.g. as a “silver bullet”) in his article.

I argue that robust markets can and will apply to software once we’ve provided the mechanisms described in the book and markets have evolved that rely on them. This would put software on the same price-performance curve that tangible goods enjoy today.

Fashioning complex conceptual constructs is the essence; accidental tasks arise in representing the constructs in language. Past progress has so reduced the accidental tasks that future progress now depends upon addressing the essence.

Of all the monsters that fill the nightmares of our folklore, none terrify more than werewolves, because they transform unexpectedly from the familiar into horrors. For these, one seeks bullets of silver that can magically lay them to rest.

The familiar software project, at least as seen by the non-technical manager, has something of this character; it is usually innocent and straightforward, but is capable of becoming a monster of missed schedules, blown budgets, and flawed products. So we hear desperate cries for a silver bullet--something to make software costs drop as rapidly as computer hardware costs do. But, as we look to the horizon of a decade hence, we see no silver bullet. There is no single development, in either technology or in management technique, that by itself promises even one order-of-magnitude improvement in productivity, in reliability, in simplicity. In this article, I shall try to show why, by examining both the nature of the software problem and the properties of the bullets proposed. Skepticism is not pessimism, however. Although we see no startling breakthroughs--and indeed, I believe such to be inconsistent with the nature of software--many encouraging innovations are under way. A disciplined, consistent effort to develop, propagate, and exploit these innovations should indeed yield an order of-magnitude improvement. There is no royal road, but there is a road

The first step toward the management of disease was replacement of demon theories and numerous theories by the germ theory. That very step, the beginning of hope, in itself dashed all hopes of magical solutions. It told workers that progress would be made stepwise, at great effort, and that a persistent, unremitting care would have to be paid to a discipline of cleanliness. So it is with software engineering today.

Does it have to be hard? --Essential difficulties

Not only are there no silver bullets now in view, the very nature of software makes it unlikely that there will be any--no inventions that will do for software productivity, reliability, and simplicity what electronics, transistors, and large-scale integration did for computer hardware.

We cannot expect ever to see two fold gains every two years.

First, one must observe that the anomaly is not that software progress is so slow, but that computer hardware progress is so fast. No other technology since civilization began has seen six orders of magnitude in performance-price gain in 30 years. In no other technology can one choose to take the gain in either improved performance or in reduced costs. These gains flow from the transformation of computer manufacture from an assembly industry into a process industry. Second, to see what rate of progress one can expect in software technology, let us examine the difficulties of that technology. Following Aristotle, I divide them into essence, the difficulties inherent in the nature of software, and accidents, those difficulties that today attend its production but are not inherent. The essence of a software entity is a construct of interlocking concepts: data sets, relationships among data items, algorithms, and invocations of functions. This essence is abstract in that such a conceptual construct is the same under many different representations. It is nonetheless highly precise and richly detailed.

I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation. We still make syntax errors, to be sure; but they are fuzz compared with the conceptual errors in most systems. If this is true, building software will always be hard. There is inherently no silver bullet. Let us consider the inherent properties of this irreducible essence of modern software systems: complexity, conformity, changeability, and invisibility.

Complexity. Software entities are more complex for their size than perhaps any other human construct because no two parts are alike (at least above the statement level). If they are, we make the two similar parts into a subroutine--open or closed. In this respect, software systems differ profoundly from computers, buildings, or automobiles, where repeated elements abound. Digital computers are themselves more complex than most things people build: They have very large numbers of states. This makes conceiving, describing, and testing them hard. Software systems have orders-of-magnitude more states than computers do. Likewise, a scaling-up of a software entity is not merely a repetition of the same elements in larger sizes; it is necessarily an increase in the number of different elements. In most cases, the elements interact with each other in some nonlinear fashion, and the complexity of the whole increases much more than linearly. The complexity of software is an essential property, not an accidental one. Hence, descriptions of a software entity that abstract away its complexity often abstract away its essence. For three centuries, mathematics and the physical sciences made great strides by constructing simplified models of complex phenomena, deriving properties from the models, and verifying those properties by experiment. This paradigm worked because the complexities ignored in the models were not the essential properties of the phenomena. It does not work when the complexities are the essence. Many of the classic problems of developing software products derive from this essential complexity and its nonlinear increases with size. From the complexity comes the difficulty of communication among team members, which leads to product flaws, cost overruns, and schedule delays. From the complexity comes the difficulty of enumerating, much less understanding, all the possible states of the program, and from that comes the unreliability. From complexity of function comes the difficulty of invoking function, which makes programs hard to use. From complexity of structure comes the difficulty of extending programs to new functions without creating side effects. From complexity of structure come the unvisualized states that constitute security trapdoors. Not only technical problems, but management problems as well come from the complexity. It makes overview hard, thus impeding conceptual integrity. It makes it hard to find and control all the loose ends. It creates the tremendous learning and understanding burden that makes personnel turnover a disaster.

Conformity. Software people are not alone in facing complexity. Physics deals with terribly complex objects even at the “fundamental” level [BJC:]. The physicist labors on, however, in a firm faith that there are unifying principles to be found, whether in quarks or in unified field theory. Einstein argued that there must be simplified [BJC: undecipherable] of nature, because God is not capricious or arbitrary. No such faith comforts the software engineer. Much of the complexity that he must master is arbitrary complexity, forced without rhyme or reason by the many human institutions and systems to which his interfaces must conform. These differ from interface to interface, and from time to time, not because of necessity but only because they were designed by different people, rather than by God.

In many cases, the software must conform because it is the most recent arrival on the scene. In others, it must conform because it is perceived as the most conformable. But in all cases, much complexity comes from conformation to other interfaces; this complexity cannot be simplified out by any redesign of the software alone.

Change:

The software entity is constantly subject to pressures for change. Of course, so are buildings, cars, computers. But manufactured things are infrequently changed after manufacture; they are superseded by later models, or essential changes are incorporated into [BJC: indecipherable] copies of the same basic design. Callbacks of automobiles are ready quite infrequent; field changes of computers somewhat less so. Both are much less frequent than modifications to fielded software.

In part, this is so because the software of a system embodies its function, and the function is the part that most feels the pressures of change. In part it is because software can be changed more easily--it is pure thought-stuff, infinitely malleable. Buildings do in fact get changed, but the high costs of change, understood by all, serve to dampen the whims of the changes.

All successful software gets changed. Two processes are at work. First, as a software product is found to be useful, people try it in new cases at the edge of or beyond the original domain. The pressures for extended function come chiefly from users who like the basic function and invent new uses for it.

Second, successful software survives beyond the normal life of the machine vehicle for which it is first written. If not new computers, than at least new disks, new displays, new printers come along; and the software must be conformed to its new vehicles of opportunity.

In short, the software product is embedded in a cultural matrix of applications, users, laws, and machine vehicles. These all change continually, and their changes inexorably force change upon the software product.

Invisibility.

Software is invisible and unvisualizable. Geometric abstractions are powerful tools. The floor plan of a building helps both architect and client evaluate spaces, traffic flows, views. Contradictions and omissions become obvious.

Despite progress in re*ic’dng and dmPlifYinB [bjc: indecipherable] software structures, they remain inherently unvisualizable, and they do not permit the mind to use some of its most powerful conceptual tools.

Scale drawings of mechanical parts and stick-figure models of molecules, although abstractions, serve the same purpose. A geometric reality is captured in a geometric abstraction.

The reality of software is not inherently embedded in space. Hence, it has no ready geometric representation in the way that land has maps, silicon chips have diagrams, and computers have connectivity schematics. As soon as we attempt to diagram software structure, we f find it to constitute not one, but several, general directed graphs superimposed one upon another. The several graphs may represent the flow of control, the flow of data, patterns of dependency, time sequence, and name-space relationships. These graphs are usually not even planar, much less hierarchical. Indeed, one of the ways of establishing conceptual control over such structure is to enforce link cutting until one or more of the graphs becomes hierarchical

In spite of progress in restricting and simplifying the structures of software, they remain inherently unvisualizable, and thus do not permit the mind to use some of its most powerful conceptual tools. This lack not only impedes the process of design within one mind, it severely hinders communication among minds.

Past Breakthroughs involved Accidental Difficulties


If we examine the three steps in software-technology development that have been most fruitful in the past, we discover that each attacked a different major difficulty in building software, but that those difficulties have been accidental, not essential, difficulties. We can also see the natural limits to the extrapolation of each such attack.

High-level languages. Surely the most powerful stroke for software productivity, reliability, and simplicity has been the progressive use of high-level languages for programming. Most observers credit that development with at least a factor of five in productivity, and with concomitant gains in reliability, simplicity, and comprehensibility.

What does a high-level language accomplish? It frees a program from much of its accidental complexity. An abstract program consists of conceptual constructs: operations, data types, sequences, and communication. The concrete machine program is concerned with bits, registers, conditions, branches, channels, disks, and such. To the extent that the high-level language embodies the constructs one wants in the abstract program and avoids all lower ones, it eliminates a whole level of complexity that was never inherent in the program at all.

The most a high-level language can do is to furnish al the constructs that the programmer imagines in the abstract program. To be sure, the level of our thinking about data structures, data types, and operations is steadily rising, but at an ever-decreasing rate.

<p>

And language development approaches closer and closer to the sophistication of users.
<p align='justify'> Moreover, at some point the elaboration of a high-level language creates a tool mastery burden that increases, not reduces, the intellectual task of the user who rarely uses the esoteric constructs.

Timesharing


Time-sharing brought a major improvement in the productivity of programmers and in the quality of their products, although not so large as that brought by high-level languages.

Time-sharing attacks a quite different difficulty. Time-sharing preserves immediacy, and hence enables one to maintain an overview of complexity. The slow turnaround of batch programming means that one inevitably forgets the minutiae, if not the very thrust, of what one was thinking when he stopped programming and called for compilation and execution. This interruption is costly in time, for one must refresh one s memory. The most serious effect may well be the decay of the grasp of all that is going on in a complex system.

Slow turnaround, like machine-language complexities, is an accidental rather than an essential difficulty of the software process.

The limits of the potential contribution of time-sharing derive directly. The principal effect of time-sharing is to shorten system response time. As this response time goes to zero, at some point it passes the human threshold of noticeability, about 100 milliseconds. Beyond that threshold, no benefits are to be expected.

Integrated Program Development Environments

Unix and Interlisp, the first integrated programming environments to come into widespread use, seem to have improved productivity by integral factors. Why?

They attack the accidental difficulties that result from using individual programs together, by providing integrated libraries, unified file formats, and pipes and filters. As a result, conceptual structures that in principle could always call, feed, and use one another can indeed easily do so in practice.

This breakthrough in turn stimulated the development of whole toolbenches, since each new tool could be applied to any programs that used the standard formats.

Because of these successes, environments are the subject of much of today s software-engineering research. We look at their promise and limitations in the next season.

Hopes for the silver

Now la us consider the technical developments that are most often advanced as potential silver bullets. What problems do they address--the problems of essence, or the remaining accidental difficulties? Do they offer revolutionary advances, or incremental ones?

One of these developments is Ada, a general-purpose high-level language of the 1980’s. Ada not only reflects evolutionary improvements in language concepts, but indeed embodies features to encourage modern design and modularization. Perhaps the Ada philosophy is more of an advance than the Ada language, for it is the philosophy of modularization, of abstract data types, of hierarchical structuring.

Ada is over-rich, a natural result of the process by which requirements were laid on its design. That is not fatal, for subsetted working vocabularies can solve the learning problem, and hardware advances will give us the cheap MIPS to pay for the compiling costs.

Advancing the structuring of software systems is indeed a very good use for the increased MIPS our dollars will buy. Operating systems, loudly decried in the 1960’s for their memory and cycle costs, have proved to be an excellent form in which to use some of the MIPS and cheap memory bytes of the past hardware surge[1] .

Nevertheless, Ada will not prove to be the silver bullet that slays the software productivity monster. It is, after all, just another high-level language, and the biggest payoff from such languages came from the first transition--the transition up from the accidental complexities of the machine into the more abstract statement of step-by-step solutions. Once those accidents have been removed, the remaining ones will be smaller, and the payoff from their removal will surely be less.

I predict that a decade from now, when the effectiveness of Ada is assessed, it will be seen to have made a substantial difference, but not because of any particular language feature, nor indeed because of all of them combined. Neither will the new Ada environments prove to be the cause of the improvements. Ada’s greatest contribution will be that switching to it occasioned training programmers in modern software-design techniques.

Object-oriented programming. Many students of the art hold out more hope for object-oriented programming than for any of the other technical fads of the day[2]. I am among them. Mark Sherman of Dartmouth notes on CSnet News that one must be careful to distinguish two separate ideas that go under that name: abstract data types and hierarchical types. The concept of the abstract data type is that an object’s type should be defined by a name, a set of proper values, and a set of proper operations rather than by its storage structure, which should be hidden. Examples are Ada packages (with private types) and Modula’s modules.

Hierarchical types, such as Simula-7’s classes, allow one to define general interfaces that can be further refined by providing subordinate types. The two concepts are orthogonal--one may have hierarchies without hiding and hiding without hierarchies. Both concepts represent real advances in the art of building software.

Each removes yet another accidental difficulty from the process, allowing the designer to express the essence of the design without having to express large amounts of syntactic material that add no information content. For both abstract types and hierarchical types, the result is to remove a higher-order kind of accidental difficulty and allow a higher-order expression of design.

Nevertheless, such advances can do no more than to remove all the accidental difficulties from the expression of the design. The complexity of the design itself is essential, and such attacks make no change whatever in that. An order-of-magnitude gain can be made by object-oriented programming only if the unnecessary type specification underbrush still in our programming language is itself nine-tenths of the work involved in designing a program product. I doubt it.

Artificial intelligence.

Many people expect advances in artificial intelligence to provide the revolutionary breakthrough that will give order-of-magnitude gains in software productivity and quality[3]. I do not. To see why, we must dissect what is meant by “artificial intelligence.”

D.L. Parnas has clarified the terminological chaos[4]: Two quite different definitions of Al are in common use today.

Al-l: The use of computers to solve problems that previously could only be solved by applying human intelligence.

Al-2: The use of a specific set of programming techniques known as heuristic or rule-based programming. In this approach human experts are studied to determine what heuristics or rules of thumb they use in solving problems.... The program is designed to solve a problem the way that humans seem to solve in

The first definition has a sliding meaning.... Something can fit the definition of Al-l today but, once we see how the program works and understand the problem, we will not think of it as Al any more.... Unfortunately I cannot identify a body of technology that is unique to this field.... Most of the work is problem-specific, and some abstraction or creativity is required to see how to transfer it.

I agree completely with this critique. The techniques used for speech recognition seem to have little in common with those used for image recognition, and both are different from those used in expert systems. I have a hard time seeing how image recognition, for example, will make any appreciable difference in programming practice. The same problem is true of speech recognition. The hard thing about building software is deciding what one wants to say, not saying it. No facilitation of expression can give more than marginal gains.

Expert-systems technology, Al-2, deserves a section of its own.

Expert systems.

The most advanced part of the artificial intelligence art, and the most widely applied, is the technology for building expert systems. Many software scientists are hard at work applying this technology to the software-building environment[[3]-[5]]. What is the concept, and what are the prospects?

An expert system is a program that contains a generalized inference engine and a rule base, takes input data and assumptions, explores the inferences derivable from the rule base, yields conclusions and advice, and offers to explain its results by tracing its reasoning for the user. The inference engines typically can deal with fuzzy or probabilistic data and rules, in addition to purely deterministic logic.

Such systems offer some clear advantages over programmed algorithms designed for arriving at the same solutions to the same problems:

Inference engine technology is developed in an application-independent way, and then applied to many uses. One can justify much effort on the inference engines. Indeed, that technology is well advanced.

The changeable parts of the application-peculiar materials are encoded in the rule base in a uniform fashion, and tools are provided for developing, changing, testing, and documenting the rule base. This regularizes much of the complexity of the application itself.

The power of such systems does not come from ever-fancier inference mechanisms, but rather from ever-richer knowledge bases that reflect the real world more accurately. I believe that the most important advance offered by the technology is the separation of the application complexity from the program itself.

How can this technology be applied to the software-engineering task? In many ways: Such systems can suggest interface rules, advise on testing strategies, remember bug-type frequencies, and offer optimization hints.

Consider an imaginary testing advisor, for example. In its most rudimentary form, the diagnostic expert system is very like a pilot’s checklist, just enumerating suggestions as to possible causes of difficulty. As more and more system structure is embodied in the rule base, and as the rule base takes more sophisticated account of the trouble symptoms reported, the testing advisor becomes more and more particular in the hypotheses it generates and the tests it recommends. Such an expert system may depart most radically from the conventional ones in that its rule base should probably be hierarchically modularized in the same way the corresponding software product is, so that as the product is modularly modified, the diagnostic rule base can be modularly modified as well.

The work required to generate the diagnostic rules is work that would have to be done anyway in generating the set of test cases for the modules and for the system. If it is done in a suitably general manner, with both a uniform structure for rules and a good difference engine available, it may actually reduce the labor of generating bring-up test cases, and bdp [bjc: indecipherable] as well with lifelong maintenance and modification testing. In the same way, one can postulate other advisors, probably many and probably simple, for the other parts of the software-construction task.

Many difficulties stand in the way of the early realization of useful expert system advisors to the program developer. A crucial part of our imaginary scenario is the development of easy ways to get from program-structure specification to the automatic or semiautomatic generation of diagnostic rules. Even more difficult and important is the twofold task of knowledge acquisition: finding articulate, self analytical experts who know why they do things, and developing efficient techniques for extracting what they know and distilling it into rule bases. The essential prerequisite for building an expert system is to have an expert.

The most powerful contribution by expert systems will surely be to put at the service of the inexperienced programmer the experience and accumulated wisdom of the best programmers. This is no small contribution. The gap between the best software engineering practice and the average practice is very wide--perhaps wider than in any other engineering discipline. A tool that disseminates good practice would be important.

Automatic programming.

For almost 40 years, people have been anticipating and writing about “automatic programming, “ or the generation of a program for solving a problem from a statement of the problem specifications. Some today write as if they expect this technology to provide the next breakthrough 5

Parnas 4 implies that the term is used for glamour, not for semantic content, asserting,

In short, automatic programming always has been a euphemism for programming with a higher-level language than was presently available to the programmer.

He argues, in essence, that in most cases it is the solution method, not the problem, whose specification has to be given.

One can find exceptions. The technique of sterling building generators is very powerful, and it is routinely used to good advantage in programs for sorting. Some systems for integrating differential equations have also permitted direct specification of the problem, and the systems have assessed the parameters, chosen from a library of methods of solution, and generated the programs

These Applications have very favorable properties:


• The problems are readily characterized by relatively few parameters.
• ? There are many known methods of solution to provide a library of alternatives.
• ? Extensive analysis has led to explicit rules for selecting solution techniques, given problem parameters.

It is hard to see how such techniques generalize to the wider world of the ordinary software system, where cases with such neat properties are the exception. It is hard even to imagine how this breakthrough in generalization could occur.

Graphical programming. A favorite subject for Ph.D. dissertations in software engineering is graphical, or visual, programming--the application of computer graphics to software design[[6][7]] Sometimes the promise held out by such an approach is postulated by analogy with VLSI chip design, in which computer graphics plays so fruitful a role. Sometimes the theorist justifies the approach by considering flowcharts as the ideal program-design medium and by providing powerful facilities for constructing them.

Nothing even convincing, much less exciting, has yet emerged from such efforts. I am persuaded that nothing will.

In the first place, as I have argued elsewhere[8], 8 the flowchart is a very poor abstraction of software structure. Indeed, it is best viewed as Burks, von Neumann, and Goldstine’s attempt to provide a desperately needed high-level control language for their proposed computer. In the pitiful, multipage, connection-boxed form to which the flowchart has today been elaborated, it has proved to be useless as a design

The development of the mass market is, I believe, the most profound long-run trend in software engineering. The cost of software has always been development cost, not replication cost. Sharing that cost among even a few users radically cuts the per-user cost. Another way of looking at it is that the use of n copies of a software system effectively multiplies the productivity of its developers by n.

That is an enhancement of the productivity of the discipline and of the nation.

The key issue, of course, is applicability. Can I use an available off the-shelf package to perform my task? A surprising thing has happened here. During the 1950’s and 1960’s, study after study showed that users would not use off-the shelf packages for payroll, inventory control, accounts receivable, and so on. The requirements were too specialized, the case-to-case variation too high. During the 1980’s, we find such packages in high demand and widespread use. What has changed?

Not the packages, really. They may be somewhat more generalized and somewhat more customizable than formerly, but not much. Not the applications, either. If anything, the business and scientific needs of today are more diverse and complicated than those of 20 years ago.

The big change has been m the hardware/software cost ratio. In 1960, the buyer of a two-million dollar machine felt that he could afford $250,000 more for a customized payroll program, one that slipped easily and nondisruptively into the computer-hostile social environment. Today, the buyer of a $50,000 office machine cannot conceivably afford a customized payroll program, so he adapts the payroll procedure to the packages available. Computers are now so commonplace, if not yet so beloved, that the adaptations are accepted as a matter of course.

There are dramatic exceptions * argument that the generation of software packages has changed little over the years: electronic spreadsheets and simple database systems. These powerful tools, 50 obvious in retrospect and *t so late in appearing, lend themselves to myriad uses, some quite unorthodox. Articles and even books now abound on how to tackle unexpected tasks with the spreadsheet.

Large numbers of applications that would formally have been written as custom programs in Cobol or Report Program Generator are now routinely done with these tools.

Many users now operate their own computers day in and day out on various applications without ever writing a program. Indeed, many of these users cannot write new programs for their machines, but they are nevertheless adept at solving new problems with them.

I believe the single most powerful software-productivity strategy for many organizations today is to equip the computer-naive intellectual workers who are on the firing line with personal computers and good generalized writing, drawing, file, and spreadsheet programs and then to turn them loose. The same strategy, carried out with generalized mathematical and statistical packages and some simple programming capabilities, will also work for hundreds of laboratory scientists.

<p> Requirements refinement and rapid prototyping.

<p align='justify'> The hardest single part of building a software system is deciding precisely what to build. No other part of the conceptual work is as difficult as establishing the detailed technical requirements, including all the interfaces to people, to machines, and to other software systems. No other part of the work so cripples the resulting system if done wrong. No other part is more difficult to rectify later.

Therefore, the most important function that the software builder performs for the client is the iterative extraction and refinement of the product requirements. For the truth is, the client does not know what he wants. The client usually does not know what questions must be answered, and he has almost never thought of the problem up the detail necessary for specification. Even the simple answer--”Make the new software system work like our old manual information-processing system” --is in far too simple. One never wants exactly that. Complex software systems are, moreover, things that act, that move, that work. The dynamics of that action are hard to imagine. So in planning any software-design activity, it is necessary to allow for an extensive iteration between the client and the designer as part of the system definition.

I would go a step further and assert that it is really impossible for a client, even working with a software engineer, to specify completely, precisely, and correctly the exact requirements of a modern software product before trying some versions of the product.

Therefore, one of the most promising of the current technological efforts, and one that attacks the essence, not the accidents, of the software problem, is the development of approaches and tools for rapid prototyping of systems as prototyping is part of the iterative specification of requirements.

A prototype software system is one that simulates the important interfaces and performs the main functions of the intended system, while not necessarily being bound by the same hardware speed, size, or cost constraints. Prototypes typically perform the mainline tasks of the application, but make no attempt to handle the exceptional tasks, respond correctly to invalid inputs, or abort cleanly.

The purpose of the prototype is to make real the conceptual structure specified, so that the client can test it for consistency and usability.

Much of present-day software-acquisition procedure rests upon the assumption that one can specify a satisfactory system in advance, get bids for its construction, have it built, and install it. I think this assumption is fundamentally wrong, and that many software-acquisition problems [[9] [10]] [11][12].

Acknowledgments

I thank Gordon Bell, Bruce Buchanan, Rick Hayes-Roth, Robert Patrick, and, most especially, David Parnas for their insights and stimulating ideas, and Rebekah Bierly for the technical production of this article.

Frederick P. Brooks is Kenan Professor of Computer Science at the University of North Carolina in Chapel Hill. He is best known as the “father of the IBM System/360 computer family,” having served as project manager for the System/360 hardware and later as project manager for the Operating System/360 software.

At Chapel Hill, Brooks founded the UNC Dept. of Computer Science and has participated in the establishment and guiding of the

Microelectronics Center of North Carolina, the Triangle Universities Computation Center, and the North Carolina Educational Computing

Service. He has received the National Medal of Technology, a Guggenheim fellowship, and the McDowell and Computer Pioneer awards of the Computer Society of the IEEE.

Brooks received his Ph.D. fin what is today computer science) from Harvard, where he was a student of Howard Aiken.
Readers may write to F.P. Brooks at the University of North Carolina, Dept. of Computer Science, Chapel Hill, NC 27514.

To slay the werewolf

Why a silver bullet? Magic, of course. Silver is identified with the moon and thus has magic properties. A silver bullet offers the fastest, most powerful, and safest way to slay the fast, powerful, and incredibly dangerous werewolf. And what could be more natural than using the moon-metal to destroy a creature transformed under the light of the full moon?

The le gend of the werewolf is probably one of the oldest monster legends around. Herodotus in the fifth century BC gave us the first written report of werewolves when he mentioned a tribe north of the Black Sea, called the Neuri, who supposedly turned into wolves a few days each year. Herodotus wrote that he didn’t t believe it.

Skeptics aside, many people have believed in people turning into wolves or other animals. In medieval Europe, some people were killed because they were thought to be werewolves. In those times, it didn’t t take being bitten by a werewolf to become one. A bargain with the devil, using a special potion, wearing a special belt, or being cursed by a witch could all turn a person into a werewolf.

However, medieval werewolves could be hurt and killed by normal weapons. The problem was to overcome their stealth and cunning.

Enter the fictional, not legendary, werewolf. The first major werewolf movie, The Werewolf/f of London, in 1935 created the two-legged man-wolf who changed into a monster when the moon was full. He became a werewolf after being bitten by one, and could be killed only with a silver bullet. Sound familiar?

Actually, we owe many of today s ideas about werewolves to Lon Chaney Jr. s unforgettable 1941 portrayal in the Wolf Man. Subsequent films seldom strayed far from the mythology of the werewolf shown in that movie. But that movie strayed far from the original mythology of the werewolf.

Would you believe that before fiction took over the legend, werewolves weren’t t troubled by silver bullets? Vampires were the ones who couldn’t t stand them. Of course, if you rely on the legends, your only salvation if unarmed and attacked by a werewolf is to climb an ash tree or run into a field of rye. Not so easy to find in an urban setting, and hardly recognizable to the average movie audience.

What should you watch out for? People whose eyebrows grow together, whose index finger is longer than the middle finger, and who have hair growing on their palms. Red or black teeth are a definite signal of possible trouble.

Take warning, though. The same symptoms mark people suffering from hypertrichosis (people born with hair covering their bodies) or porphyria. In porphyria, a person s body produces toxins called porphyrlns. Consequently, light becomes painful, the skin grows hair, and the teeth may turn red. Worse for the victim’s s reputation, his or her increasingly bizarre behavior makes people even more suspicious of the other symptoms. It seems very likely that the sufferers of this disease unwittingly contributed to the current legend, although in earlier times they were evidently not accused of murderous tendencies.

References

[1] D.L. Parnas, “Designing Software for Ease of Extension and Contraction,” IEEE Trans. Software Engineering, Vol. 5, No. 2, Mar. 1979, pp. 128-138.

[2] G. Booch, “Object-oriented Design,” Software Engineering with Ada, 1983, Benjamin/Cummings, Menlo Park, Calif.

[3] IEEE Trans. Software Engineering (special issue on artificial intelligence and software engineering), J. Mostow, guest ed., Vol. 11, No. 11, Nov. 1985.

[4] D.L. Parnas, “Software Aspects of Strategic Defense Systems,” American Scientist, Nov. 1985.

[5] R. Baker, “A 15-Year Perspective on Automatic Programming,” IEEE Trans. Software Engineering (special issue on artificial intelligence and software engineering), *. Mostow, guest ed., Vol. 11, No. 11, Nov. 1985, pp. 1257-1267.

[6] Computer (special issue on visual programming), R.B. Graphton and T. Ichikawa, guest eds., Vol. 18, No. 8, Aug. 1985.

[7] G. Raeder, “A Survey of Current Graphical Programming Techniques,” Computer (special issue on visual programming), R.B. Graphton and T. Ichikawa, guest eds., Vol.18, No. 8, Aug. 1985, pp. 11-25.

[8] F.P. Brooks, The Mythical Man-Month, 1975, Addison-Wesley, Reading, Mass., New York, Chapter 14.
[9] Defense Science Board, Report of the Task Force on Military Software, in press.

[10] H.D. Mills, “Top-Down Programming in Large Systems,” in Debugging Techniques in Large Systems, R. Ruskin, ed., Prentice-Hall, Englewood Cliffs, N.*., 1971.

[11] B.W. Boehm, “A Spiral Model of Software Development and Enhancement,” 1985, TRW tech. report 21-371-85, TRW, Inc., I Space Park, Redondo Beach, CA 90278.

[12] H. Sackman, W.J. Erikson, and E.E. Grant, “Exploratory Experimental Studies Comparing Online and Offline Programming Performance,” CACM, Vol. Il,No. I,Jan. 1968,pp.3-11.

It is worth noting that the film tradition often makes the werewolf a rather sympathetic character, an Innocent transformed against monster. As the gypsy said In The Wolf Man,

Even a man who is pure at heart,

And says his prayers at night,

Can become a wolf when the wolfbane blooms,

And the moon is full and bright.



Anexo 3



Construcción de Aplicaciones en Capas

Generalidades

La construcción de aplicaciones n-tier (n-capas) distribuidas ha emergido como la arquitectura predominante para la construcción de aplicaciones multiplataforma en la mayor parte de las empresas. Este cambio radical en los modelos de computación, desde los sistemas monolíticos basados en mainframe y los tradicionales sistemas cliente-servidor, hacia sistemas distribuidos multiplataforma altamente modularles, representa el desarrollo rápido y avance de la investigación en el mundo del desarrollo de aplicaciones, tal y como se pone de manifiesto en las últimas tendencias de las grandes empresas de tecnología, como Sun con su estrategia Sun One, o Microsoft con DotNET (.Net).

El modelo presenta algunas ventajas entre ellas:

• Desarrollos paralelos (en cada capa)
• Aplicaciones más robustas debido al encapsulamiento
• Mantenimiento y soporte más sencillo (es más sencillo cambiar un componente que modificar una aplicación monolítica)
• Mayor flexibilidad (se pueden añadir nuevos módulos para dotar al sistema de nueva funcionalidad)

• Alta escalabilidad. La principal ventaja de una aplicación distribuida bien diseñada es su buen escalado, es decir, que puede manejar muchas peticiones con el mismo rendimiento simplemente añadiendo más hardware. El crecimiento es casi lineal y no es necesario añadir más código para conseguir esta escalabilidad.

Como tecnología, las arquitecturas de n-capas proporcionan una gran cantidad de beneficios para las empresas que necesitan soluciones flexibles y fiables para resolver complejos problemas inmersos en cambios constantes. Todas las aplicaciones basadas en n-capas permitirán trabajar con clientes ligeros, tal como navegadores de Internet, WebTV, Teléfonos Inteligentes, PDAs (Personal Digital Assistants o Asistentes Personales Digitales) y muchos otros dispositivos preparados para conectarse a Internet. De este modo, las arquitecturas de n-capas se están posicionando rápidamente como la piedra angular de los desarrollos de aplicaciones empresariales y las compañías están adoptando esta estrategia a una velocidad de vértigo como mecanismo de posicionamiento en la economía emergente que tiene su base en la red (lo que se ha venido a denominar "Nueva Economía"). Actualmente, la Red (Internet, intranets y extranets) es el ordenador o, como diría Sun Microsystems, el ordenador es la Red. Este paradigma está creando un cambio fundamental en los modelos de computación que, a su vez, proporciona desafíos y oportunidades como nunca antes había se habían producido. Realmente, los componentes distribuidos de una arquitectura de n-capas es una tecnología esencial para crear la siguiente generación de aplicaciones e-business, aplicaciones que son altamente escalables, fiables y que proporcionan un alto rendimiento y una integración sin fisuras con los sistemas de back-end heredados. A diferencia de lo que se pudiera pensar, el desarrollo en n-capas no es un producto o un estándar, es un concepto estratégico que ayuda a la construcción y despliegue lógico de un sistema distribuido. Los sistemas de n-capas subdivididos ayudan a facilitar el desarrollo rápido de aplicaciones y su posterior despliegue, con beneficios incrementales fruto de los esfuerzos del desarrollo en paralelo coordinado y del outsourcing inteligente, resultando un enorme decremento del tiempo de desarrollo y de sus costes. Muchas de las aplicaciones de e-business que se utilizan actualmente simplemente utilizan un navegador de Internet como cliente ligero que implementa una interfaz universal. Una arquitectura basada en clientes ligeros desplaza la capa de presentación de la aplicación en el lado del cliente, mientras que la lógica de negocio y los datos residen en el middleware y los servidores de back-end. El diseño para clientes ligeros minimiza los problemas de despliegue de las aplicaciones, mientras que maximiza la accesibilidad a la misma desde una amplia variedad de plataformas heterogéneas. Los frameworks basados en n-capas se crean para obtener las ventajas de los estándares abiertos de la industria que permiten a las aplicaciones resultantes operar en entornos distribuidos multiplataforma.

CARACTERÍSTICAS

Las aplicaciones que se construyen con una arquitectura multicapa tienen entre otras las siguientes características:


  • Acceso a bases de datos (BD)
o Normalmente con BD relacionales
  • Transaccionales
oPropiedades ACID (Atomicity-Consistency-Isolation-Durability)

• Operaciones atómicas (Atomicity) son operaciones que se completan en su totalidad o no se completan en absoluto. Así, en el ejemplo anterior de la transferencia tanto el crédito como el débito deben haber sido exitosos para que el estado de transformación sea exitoso (para que haga efectos), de otro modo el estado de la transformación falla, y el sistema es regresado a su último estado conocido.

• Transformaciones consistentes (Consistency) preservan la integridad interna de los recursos involucrados. Por ejemplo, el borrar registros de una tabla primaria viola la integridad referencial de la base de datos si hay registros relacionados que concuerden.

• Transformaciones aisladas (Isolation) parecen ocurrir serialmente, una detrás de otra, creando la ilusión de que ninguna transformación está siendo ejecutada al mismo tiempo.

• La durabilidad (Durability) se refiere a la habilidad para almacenar los resultados de una transformación de estado, usualmente en un disco, de tal modo que los resultados de una transformación puedan ser recuperados en caso de una falla del sistema.


  • Escalables
o Deberían poder soportar más carga de trabajo sin necesidad de modificar el software (sólo añadir más máquinas).
  • Disponibilidad
o Idealmente no deben dejar de prestar servicio.
  • Seguras
o No todos los usuarios pueden acceder a la misma funcionalidad.
  • Integración
o Es preciso integrar aplicaciones construidas con distintas tecnologías.
  • Tipo de interfaz
o De entorno de ventanas (clientes desktop): normalmente sólo tiene sentido en intranets.
o Web: En Internet y en intranets.
  • Separación clara entre la interfaz gráfica y la Capa de componentes
o Capa de componentes: encapsulan la lógica de negocio.
o Ejemplo => aplicación bancaria.

- Capa de componentes: conjunto de clases que nos permiten: crear cuentas, destruirlas, encontrarlas por distintos criterios, hacer transferencias bancarias, etc.

o La capa de componentes debería ser reusable con distintas interfaces gráficas.
o En el ejemplo de la aplicación bancaria podría haber dos clientes: uno Web y otro desktop.

APLICACIONES DE UNA CAPA

Las capas dentro de una arquitectura son nada más que un conjunto de servicios especializados que pueden ser accesibles por múltiples clientes y fácilmente reutilizables.

Este tipo de arquitectura se caracteriza por tener en una sola asociación lógica y en ella a la presentación, la lógica de negocios y los datos; que si los ponemos como servicios se convierten en capas, lo veremos más adelante.

Imagen:Anexo_3.JPG

Ejemplos de esta arquitectura son desarrollos realizados en Excel, Access, Fox, entre otros.

APLICACIONES DE DOS CAPAS

Se caracterizan por tener 2 asociaciones lógicas, que prestan servicios y que a la final son capas.

Imagen:Anexo_3_2.JPG
Arquitectura Cliente – Servidor

Pero quisiera plantear la siguiente problemática:

¿Qué podría suceder si tuviésemos que hacer cambios en la implementación de la lógica de negocios? El resultado es la recompilación de toda la aplicación y reinstalación en todos y cada uno de los clientes; y….si mis clientes suman como 200 máquinas?

La solución está en separar la lógica de negocios en un servicio aparte, allí es donde aparece la tercera capa.

APLICACIONES DE 3 CAPAS

Una aplicación de tres capas es una aplicación cuya funcionalidad puede ser segmentada en tres niveles lógicos (capas):

• Los servicios de presentación.
• Los servicios de negocios (Lógica de Negocios)
• Los servicios de datos.
Imagen:Anexo_3_3.JPG
Arquitectura de Aplicaciones de 3 capas

La capa de servicios de presentación es responsable de:

• Obtener información del usuario.
• Enviar la información del usuario a los servicios de negocios para su procesamiento.
• Recibir los resultados del procesamiento de los servicios de negocios.
• Presentar estos resultados al usuario.

El nivel de servicios de negocios es responsable de:

• Recibir la entrada del nivel de presentación.

• Interactuar con los servicios de datos para ejecutar las operaciones de negocios para los que la aplicación fue diseñada a automatizar (por ejemplo, la preparación de impuestos por ingresos, el procesamiento de ordenes y así sucesivamente).

• Enviar el resultado procesado al nivel de presentación.

El nivel de servicios de datos es responsable de:

• Almacenar los datos.
• Recuperar los datos.
• Mantener los datos.
• La integridad de los datos.
Imagen:Anexo_3_4.JPG
Arquitectura de 3 capas

Al ser la primera capa un servicio, se puede inferir que las aplicaciones no solo podrían ser de escritorio, si quisiéramos que nuestra aplicación tenga una interface web, pues solamente bastaría con cambiar la capa de presentación y de allí en adelante nada tiene porque cambiar. Entonces nuestras páginas web estarían alojadas en un Servidor Web las mismas que se conectan a la lógica de negocios y de allí a los servicios de datos.

Imagen:Anexo_3_5.JPG
Arquitectura de 3 capas con interface Web

APLICACIONES DE N CAPAS

Podríamos ir separando nuestra aplicación en mas niveles lógicos, por ejemplo, vamos a querer que nuestra aplicación tenga múltiples interfaces, es decir interface gráfica (standalone o desktop) y también interface Web. Lo aconsejado en esta circunstancia es separar al Servidor Web encargado de alojar las páginas Web en una capa más. En este caso se tendrían 4 capas.

Imagen:Anexo_3_6.JPG
Arquitectura de 4 capas

Mientras más servicios coloquemos a nuestra aplicación y mientras más escalable lo imaginemos, mas capas lógicas van a irse añadiendo a nuestra arquitectura; allí está el inicio del estudio de las siguientes secciones del curso, LOS PATRONES DE DISEÑO.

• La arquitectura en 3 capas es la más usada
• La arquitectura en 4 capas puede ser más escalable

Desarrollo de aplicaciones basadas en componentes

El surgimiento de la tecnología de componentes distribuidos es la clave de las arquitecturas de n-capas. Estos sistemas de computación utilizan un número variable de componentes individuales que se comunican entre ellos utilizando estándares predefinidos y frameworks de comunicación como:

• CORBA: (Common Object Request Broker Architecture) del Object Management Group (OMG).
• DNA : (Distributed Network Applications) de Microsoft (incluye COM/DCOM y COM+ además de MTS, MSMQ, etc.).
• EJB : (Enterprise Java Beans) de Sun Microsystems.
• XML : (eXtensible Markup Language) del World Wide Web Consortium (W3C).
• .NET: de Microsoft que incluye nuevos lenguajes como Visual Basic.net, C#.

Estas y otras tecnologías en rápida evolución proporcionan la infraestructura necesaria que permite a las compañías operar en un entorno complejo, multiplataforma y con capacidades de computación distribuida, tanto interna como externamente según se requiera en cada.



Anexo 4



Patrones de diseño

INTRODUCCIÓN

La construcción de aplicaciones de software es una de las tareas más complicadas, la cual depende en gran medida de la experiencia de las personas involucradas, en particular de los desarrolladores.

El 80% de los aportes vienen del 20% del personal.

La comprensión del software es uno de los problemas más complicados en la tarea de mantenimiento y evolución.

El hombre durante su historia ha dominado cierta técnica pasando por un proceso:

• Se realizan las operaciones de una manera artesanal.
• Los expertos aprenden por un proceso de ensayo y error y por transmisión de otros expertos.
• Se crea una ciencia alrededor de la tarea.
• Se desarrollan las técnicas generalmente aceptadas en el área.
• Se logra un conocimiento común sobre cómo aplicar las técnicas.
• Hay un metalenguaje común ente los expertos.

La sociedad requiere sistemas más complejos y más grandes. Los recursos para desarrollarlos cada vez son más escasos. Debe existir un mecanismo de reutilización.

El 80% del esfuerzo esta en el 20% del código desarrollado.

Uno de los objetivos que se buscan al utilizar esta técnica es conseguir la reutilización. Entre los beneficios que se consiguen con la reutilización están:

• Reducción de tiempos.
• Disminución del esfuerzo de mantenimiento.
• Eficiencia.
• Consistencia.
• Fiabilidad.
• Protección de la inversión en desarrollos.

Entre los diferentes mecanismos de reutilización están:

Componentes: elemento de software suficientemente pequeño para crearse y mantenerse pero suficientemente grande para poder utilizarse.

Frameworks: bibliotecas de clases preparadas para la reutilización que pueden utilizar a su vez componentes.

Objetos distribuidos: paradigma que distribuye los objetos de cooperación a través de una red heterogénea y permite que los objetos interoperen como un todo unificado.

Patrones de diseño.
- Sin embargo los mecanismos de reutilización también presentan algunos obstáculos:
• El síndrome No Inventado Aquí: los desarrolladores de software no se suelen fiar de lo que no está supervisado por ellos mismos.
• Acceso a los fuentes de componentes y frameworks.
• Impedimentos legales, comerciales o estratégicos.
• Formato de distribución de componentes (CORBA, ActiveX,...).
• Dilema entre reutilizar y rehacer.
• Existe una inercia personal a los cambios

Se debe ser consumidor de reutilización antes de ser un productor de reutilización.

Historia

Los patrones como elemento de la reutilización, comenzaron a utilizarse en la arquitectura con el objetivo de reutilizar diseños que se habían aplicado en otras construcciones y que se catalogaron como completos.

Christopher Alexander fue el primero en intentar crear un formato específico para patrones en la arquitectura. Alexander argumenta que los métodos comunes aplicados en la arquitectura dan lugar a productos que no satisfacen las demandas y requerimientos de los usuarios y son ineficientes a la hora de conseguir el propósito de todo diseño y esfuerzo de la ingeniería: mejorar la condición humana.

Christopher Alexander da la siguiente definición de patrón:

“Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, para describir después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada más de un millón de veces sin hacerlo ni siquiera dos veces de la misma forma”.

Si nos fijamos en las construcciones de una determinada zona rural observaremos que todas ellas poseen apariencias parejas (tejados de pizarra con gran pendiente, etc.), pese a que los requisitos personales por fuerza han debido ser distintos. De alguna manera la esencia del diseño se ha copiado de una construcción a otra, y a esta esencia se pliegan de forma natural los diversos requisitos.

Se puede ver que aquí que existe un patrón que soluciona de forma simple y efectiva los problemas de construcción en tal zona.

En definitiva se puede definir un patrón como “una solución a un problema en un determinado contexto”.

El término patrón se utiliza inicialmente en el campo de la arquitectura, por Christopher Alexander, a finales de los 70’s. Este conocimiento es transportado al ámbito del desarrollo de software orientado a objetos y se aplica al diseño. De allí es extrapolado al desarrollo en general y a las demás etapas. En 1987, Ward Cunningham y Kent Beck trabajaron con Smaltalk y diseñaron interfaces de usuario. Decidieron, para ello, utilizar alguna de las ideas de Alexander para desarrollar un lenguaje pequeño de patrones para servir de guía a los programadores de Smaltalk. Así dieron lugar al libro “Using Pattern Languajes for Object-Oriented Programs”. Poco después, Jim Coplien comenzó a realizar un catálogo de idioms (que son un tipo de patrones) en C++ y publica su libro “Advanced C++ Programming Styles and Idioms” en 1991. Desde 1990 a 1994, Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides (el grupo de los cuatro) realizaron un primer catálogo de patrones de diseño. Posteriormente hubo diferentes discusiones a cerca de los patrones en las que participaron notables personalidades de los patrones. Poco después de Abril de 1994 el libro “Design Patterns: Elements of Reusable Object- Oriented Software” (Gang of Four, [GoF]) es publicado, el mismo que es el libro base de nuestro curso.

Patrones de software

Los patrones para el desarrollo de software son uno de los últimos avances de la Tecnología Orientada a Objetos. Los patrones son una forma literaria para resolver problemas de ingeniería del software, que tienen sus raíces en los patrones de la arquitectura. Los diseñadores y analistas de software más experimentados aplican de forma intuitiva algunos criterios que solucionan los problemas de manera elegante y efectiva. La ingeniería del software se enfrenta a problemas variados que hay que identificar para poder utilizar la misma solución (aunque matizada) con problemas similares.

Las metodologías Orientadas a Objetos tienen como uno de sus principios “no reinventar la rueda” para la resolución de diferentes problemas.

El objetivo de los patrones es crear un lenguaje común a una comunidad de desarrolladores para comunicar experiencia sobre los problemas y sus soluciones.

Características

Hay que tener en cuenta que no todas las soluciones que tengan, en principio, las características de un patrón son un patrón, sino que debe probarse que es una solución a un problema que se repite.

Los buenos patrones deben tener las siguientes características:

• Solucionar un problema: los patrones capturan soluciones, no sólo principios o estrategias abstractas.
• Ser un concepto probado: los patrones capturan soluciones demostradas, no teorías o especulaciones.
• La solución no es obvia: muchas técnicas de solución de problemas tratan de hallar soluciones por medio de principios básicos.

Los mejores patrones generan una solución a un problema de forma indirecta.

• Describe participantes y relaciones entre ellos: los patrones no sólo describen módulos sino estructuras del sistema y mecanismos más complejos.

• El patrón tiene un componente humano significativo: todo software proporciona a los seres humanos confort o calidad de vida (estética y utilidad).

Los patrones indican repetición, si algo no se repite, no es posible que sea un patrón. Pero la repetición no es la única característica importante. También necesitamos mostrar que un patrón se adapta para poder usarlo, y que es útil. La repetición es una característica cuantitativa pura, la adaptabilidad y utilidad son características cualitativas. Podemos mostrar la repetición simplemente aplicando la regla de tres (en al menos tres sistemas existentes); mostrar la adaptabilidad explicando como el patrón es exitoso; y mostrar la utilidad explicando porque es exitoso y beneficioso.

Elementos

En general, un patrón tiene cuatro elementos esenciales:

1.  El nombre del patrón se utiliza para describir un problema de diseño, su solución, y consecuencias en una o dos palabras.

Nombrar un patrón incrementa inmediatamente nuestro vocabulario de diseño. Esto nos permite diseños a un alto nivel de abstracción.

Tener un vocabulario de patrones nos permite hablar sobre ellos con nuestros amigos, en nuestra documentación, e incluso a nosotros mismos.

2.  El problema describe cuando aplicar el patrón. Se explica el problema y su contexto. Esto podría describir problemas de diseño específicos tales como algoritmos como objetos. Podría describir estructuras de clases o objetos que son sintomáticas de un diseño inflexible. Algunas veces el problema incluirá una lista de condiciones que deben cumplirse para poder aplicar el patrón.

3.  La solución describe los elementos que forman el diseño, sus relaciones, responsabilidades y colaboraciones. La solución no describe un diseño particular o implementación, porque un patrón es como una plantilla que puede ser aplicada en diferentes situaciones. En cambio, los patrones proveen una descripción abstracta de un problema de diseño y como una disposición general de los elementos (clases y objetos en nuestro caso) lo soluciona.

4.  Las consecuencias son los resultados de aplicar el patrón. Estas son muy importantes para la evaluación de diseños alternativos y para comprender los costos y beneficios de la aplicación del patrón.

Los patrones de diseño tienen un cierto nivel de abstracción. Los patrones de diseño no son diseños tales como la realización de listas y tablas hash que pueden ser codificadas en clases y reutilizadas. Un algoritmo puede ser un ejemplo de implementación de un patrón, pero es demasiado incompleto, específico y rígido para ser un patrón. Una regla o heurística puede participar en los efectos de un patrón, pero un patrón es mucho más. Los patrones de diseño son descripciones de las comunicaciones de objetos y clases que son personalizadas para resolver un problema general de diseño en un contexto particular.

Descripción

¿Cómo describimos los patrones de diseño? Las notaciones gráficas, aunque importantes y útiles, no son suficientes. Estás solo recogen el producto final del proceso de diseño como las relaciones entre clases y objetos. Para describir los patrones de diseño se utiliza un formato consistente. Cada patrón es dividido en secciones de acuerdo con la siguiente plantilla. La plantilla nos muestra una estructura uniforme para la información, de tal forma que los patrones de diseño sean fáciles de aprender, comparar y utilizar.

Nombre
Propósito
- ¿Qué hace?, ¿Cuál es su razón y propósito?, ¿Qué cuestión de diseño particular o problema aborda?
Sinónimos
Motivación
- Escenario que ilustra un problema particular y cómo el patrón lo resuelve.
Aplicabilidad
- ¿En qué situaciones puede aplicarse, ¿Cómo las reconoces?, ejemplos de diseños que pueden mejorarse.
Estructura
- Diagramas de clases que ilustran la estructura.
Participantes
- Clases que participan y sus responsabilidades
Colaboraciones
• Diagramas de interacción que muestran cómo colaboran los participantes.
Consecuencias

- ¿Cómo alcanza el patrón sus objetivos?, ¿Cuáles son los compromisos y resultados de usar el patrón?, Alternativas, Costos y Beneficios

Implementación
- Técnicas, heurísticas y consejos para la implementación
- ¿Hay cuestiones dependientes del lenguaje?
Ejemplo de Código
Usos conocidos
Patrones relacionados

Clasificación

Dado que hay muchos patrones de diseño se necesita un modo de organizarlos. En esta sección clasificamos los patrones de diseño de tal forma que podamos referirnos a familias de patrones relacionados.

Imagen:Anexo_4.JPG

Patrones y Frameworks

Un framework es una colección organizada de clases que constituyen un diseño reutilizable para una clase específica de software.

• Necesario adaptarlo a una aplicación particular.
• Establece la arquitectura de la aplicación

Los frameworks pueden incluir patrones de diseño. Sin embargo hay que distinguirlos los frameworks son ejecutables mientras que los patrones de diseño representan un conocimiento o experiencia sobre software. Un framework se puede ver como la implementación de un sistema de patrones de diseño. Los frameworks son de naturaleza física, mientras que los patrones son de naturaleza lógica: los frameworks son la realización física de uno o varios patrones de soluciones software; los patrones son las instrucciones de cómo implementar estas soluciones.

Las principales diferencias entre patrones de diseño y frameworks son:

1.  Los patrones de diseño son más abstractos que los frameworks. Los frameworks pueden ser codificados, pero solo los ejemplos de patrones de diseño pueden ser codificados. Una característica de los frameworks es que pueden ser escritos bajo lenguajes de programación y no solamente estudiados para ejecutarse y reutilizarse directamente. En cambio, los patrones de diseño tienen que ser implementados cada vez que son usados. Los patrones de diseño también explican el objetivo, los cambios y las consecuencias de un diseño.

2.  Los patrones de diseño son elementos arquitectónicos más pequeños que los frameworks. Un framework contiene varios patrones de diseño, lo contrario nunca es cierto.

3.  Los patrones de diseño están menos especializados que los frameworks. Los frameworks siempre tienen un dominio particular de aplicación. En cambio, los patrones de diseño pueden ser utilizados en cualquier tipo de aplicación.

Herramientas personales
Sitios UTPL