Articulo de referencia

Diseño de software

El diseño de software es el proceso de conceptualizar cómo funcionará un sistema de software antes de su implementación o modificación. [ 1 ] El diseño de software también se re...

El diseño de software es el proceso de conceptualizar cómo funcionará un sistema de software antes de su implementación o modificación. [ 1 ] El diseño de software también se refiere al resultado directo del proceso de diseño : los conceptos de cómo funcionará el software, que pueden estar documentados formalmente o mantenerse de manera menos formal, incluso a través de la tradición oral .

El proceso de diseño permite al diseñador modelar aspectos de un sistema de software antes de que exista, con el fin de optimizar el trabajo de escribir el código. La creatividad, la experiencia previa, la comprensión de lo que constituye un buen software y el compromiso con la calidad son factores clave para un diseño competente.

El diseño de un software puede compararse con el plano arquitectónico de una casa . Los planos generales representan la totalidad de la vivienda (por ejemplo, una representación tridimensional). Los planos más detallados proporcionan orientación para la construcción de cada elemento (por ejemplo, la disposición de las tuberías). De manera similar, el modelo de diseño del software ofrece diversas perspectivas de la solución propuesta.

Parte del proceso general

En términos del proceso de desarrollo en cascada , el diseño de software es la actividad que ocurre después del análisis de requisitos y antes de la codificación . [ 2 ] El análisis de requisitos determina qué debe hacer el sistema sin determinar cómo lo hará, por lo que se pueden imaginar múltiples diseños que satisfagan los requisitos. El diseño se puede crear durante la codificación, sin un plan ni un análisis de requisitos, [ 3 ] pero para proyectos más complejos esto es menos factible. Completar un diseño antes de la codificación permite que diseñadores multidisciplinarios y expertos en la materia colaboren con los programadores para producir software que sea útil y técnicamente sólido.

En ocasiones, se crea una simulación o un prototipo para modelar el sistema con el fin de determinar un diseño válido y adecuado.

El código como diseño

Un punto común de confusión con el término diseño en software es que el proceso se aplica en múltiples niveles de abstracción , como una arquitectura de software de alto nivel y componentes, funciones y algoritmos de bajo nivel . Un proceso relativamente formal puede ocurrir en niveles altos de abstracción, pero en niveles inferiores, el proceso de diseño es casi siempre menos formal, donde el único artefacto de diseño puede ser el código mismo. En la medida en que esto sea cierto, el diseño de software se refiere al diseño del diseño. Edsger W. Dijkstra se refirió a esta estratificación de niveles semánticos como la "novedad radical" de la programación informática, [ 4 ] y Donald Knuth utilizó su experiencia escribiendo TeX para describir la inutilidad de intentar diseñar un programa antes de implementarlo:

T E X habría sido un completo fracaso si me hubiera limitado a especificarlo y no hubiera participado plenamente en su implementación inicial. El proceso de implementación me llevó constantemente a preguntas imprevistas y a nuevas perspectivas sobre cómo mejorar las especificaciones originales. [ 5 ]

Artefactos

Ejemplo de diagrama de flujo de software

Un proceso de diseño puede incluir la producción de documentación de diseño de software, como diagramas de flujo , casos de uso , pseudocódigo , modelos en lenguaje unificado de modelado (UML) y otros conceptos fundamentales de modelado . Para software centrado en el usuario , el diseño puede implicar el diseño de la experiencia del usuario, lo que da como resultado un guion gráfico que ayuda a determinar las especificaciones. La documentación puede revisarse para permitir el ajuste de restricciones, especificaciones e incluso requisitos antes de la codificación.

Diseño iterativo

Los sistemas de software, por su propia naturaleza, se enfrentan a incertidumbres, y el tamaño de sus componentes puede influir significativamente en los resultados del sistema, tanto positiva como negativamente. Neal Ford y Mark Richards proponen un enfoque iterativo para abordar el desafío de identificar y dimensionar correctamente los componentes. Este método enfatiza el perfeccionamiento continuo a medida que los equipos desarrollan una comprensión más profunda del comportamiento y los requisitos del sistema. [ 6 ]

El enfoque generalmente implica un ciclo con varias etapas: [ 6 ]

  • Se establece una estrategia de particionamiento de alto nivel, que suele clasificarse como técnica o basada en dominios. Se definen las directrices para la unidad desplegable más pequeña y significativa, denominada «quanta». Si bien estas decisiones fundamentales se toman al inicio del ciclo, pueden revisarse posteriormente si fuera necesario.
  • Los componentes iniciales se identifican en función de la estrategia establecida.
  • Se asignan requisitos a los componentes identificados.
  • Se analizan las funciones y responsabilidades de cada componente para garantizar la claridad y minimizar la superposición de funciones.
  • Se evalúan características arquitectónicas como la escalabilidad, la tolerancia a fallos y la facilidad de mantenimiento.
  • Los componentes pueden reestructurarse en función de los comentarios de los equipos de desarrollo.

Este ciclo sirve como marco general y puede adaptarse a diferentes ámbitos.

Principios de diseño

Los principios de diseño permiten a un ingeniero de software navegar por el proceso de diseño. Davis [ 7 ] sugirió principios que se han perfeccionado con el tiempo, como:

El proceso de diseño no debe sufrir de "visión de túnel".
Un buen diseñador debe considerar enfoques alternativos, evaluando cada uno en función de los requisitos del problema y los recursos disponibles para realizar el trabajo.
El diseño debe ser rastreable hasta el modelo de análisis.
Dado que un solo elemento del modelo de diseño a menudo puede vincularse a múltiples requisitos, es necesario contar con un medio para rastrear cómo el modelo de diseño ha satisfecho dichos requisitos.
El diseño no debe reinventar la rueda.
Los sistemas se construyen utilizando un conjunto de patrones de diseño, muchos de los cuales probablemente ya se hayan visto antes. Estos patrones siempre deben elegirse como alternativa a la reinvención. El tiempo es escaso y los recursos limitados; el tiempo de diseño debe invertirse en representar ideas (verdaderamente nuevas) mediante la integración de patrones ya existentes (cuando corresponda).
El diseño debe "minimizar la distancia intelectual" entre el software y el problema tal como existe en el mundo real.
Es decir, la estructura del diseño del software debería, siempre que sea posible, imitar la estructura del dominio del problema.
El diseño debe mostrar uniformidad e integración.
Un diseño es uniforme si presenta una coherencia total. Para lograrlo, es necesario definir las reglas de estilo y formato para el equipo de diseño antes de que comience el trabajo. Un diseño está integrado si se presta atención a la definición de las interfaces entre sus componentes.
El diseño debe estar estructurado para adaptarse a los cambios.
Los conceptos de diseño que se analizan en la siguiente sección permiten que un diseño cumpla con este principio.
El diseño debe estar estructurado para degradarse gradualmente, incluso cuando se presenten datos, eventos o condiciones de funcionamiento anómalos.
Un software bien diseñado nunca debería "fallar"; debería estar diseñado para adaptarse a circunstancias inusuales y, si debe finalizar el procesamiento, debería hacerlo de forma controlada.
El diseño no es programación, la programación no es diseño.
Incluso cuando se crean diseños procedimentales detallados para los componentes del programa, el nivel de abstracción del modelo de diseño es superior al del código fuente. Las únicas decisiones de diseño que se toman a nivel de codificación deben abordar los pequeños detalles de implementación que permiten codificar el diseño procedimental.
El diseño debe evaluarse en cuanto a su calidad mientras se está creando, no después de su creación.
Se dispone de diversos conceptos y medidas de diseño para ayudar al diseñador a evaluar la calidad a lo largo de todo el proceso de desarrollo.
El diseño debe revisarse para minimizar los errores conceptuales (semánticos).
En ocasiones, al revisar un diseño, se tiende a centrarse en detalles insignificantes, perdiendo de vista el panorama general. Un equipo de diseño debe asegurarse de que se hayan abordado los elementos conceptuales principales (omisiones, ambigüedad, inconsistencia) antes de preocuparse por la sintaxis del modelo de diseño.

Conceptos de diseño

Los conceptos de diseño proporcionan al diseñador una base a partir de la cual se pueden aplicar métodos más sofisticados. Los conceptos de diseño incluyen:

Abstracción
Reducir el contenido informativo de un concepto o fenómeno observable, generalmente para conservar solo la información relevante para un propósito específico. Se trata de representar las características esenciales sin incluir detalles ni explicaciones adicionales.
Arquitectura
La estructura general del software y la forma en que dicha estructura proporciona integridad conceptual al sistema. Una buena arquitectura de software generará un buen retorno de la inversión con respecto al resultado deseado del proyecto, por ejemplo, en términos de rendimiento, calidad, plazos y costes.
Jerarquía de control
Una estructura de programa que representa la organización de un componente del programa e implica una jerarquía de control.
Estructura de datos
Representar la relación lógica entre los elementos de los datos.
Patrón de diseño
Un diseñador puede identificar un aspecto del diseño del sistema que se haya resuelto en el pasado. La reutilización de dichos patrones puede aumentar la velocidad de desarrollo del software. [ 8 ]
Ocultación de información
Los módulos deben especificarse y diseñarse de manera que la información contenida en un módulo sea inaccesible para otros módulos que no necesiten dicha información.
Modularidad
Dividir la solución en partes (módulos).
Refinamiento
El proceso de elaboración. Se desarrolla una jerarquía descomponiendo una instrucción macroscópica de una función paso a paso hasta llegar a las instrucciones del lenguaje de programación. En cada paso, una o varias instrucciones de un programa dado se descomponen en instrucciones más detalladas. Abstracción y refinamiento son conceptos complementarios.
Procedimiento de software
Se centra en el procesamiento de cada módulo individualmente.
Particionamiento estructural
La estructura del programa se puede dividir horizontal y verticalmente. Las particiones horizontales definen ramas separadas de la jerarquía modular para cada función principal del programa. La partición vertical sugiere que el control y el trabajo deben distribuirse de arriba hacia abajo en la estructura del programa.

Grady Booch menciona la abstracción , la encapsulación , la modularización y la jerarquía como principios fundamentales del diseño de software. [ 9 ] La frase principios de jerarquía, abstracción, modularización y encapsulación (PHAME) se refiere a estos principios. [ 10 ]

Consideraciones de diseño

En el diseño de software hay muchos aspectos a considerar. La importancia de cada uno debe reflejar los objetivos y las expectativas para los que se crea el software. Algunos aspectos destacables son:

Compatibilidad
El software puede funcionar con otros productos diseñados para la interoperabilidad. Por ejemplo, un programa puede ser compatible con versiones anteriores.
Extensibilidad
Se pueden añadir nuevas funcionalidades al software sin necesidad de realizar cambios importantes en la arquitectura subyacente.
Tolerancia a fallos
El software es resistente a los fallos de los componentes y es capaz de recuperarse de ellos.
Mantenibilidad
Una medida de la facilidad con la que se pueden corregir errores o realizar cambios en las funciones. Una alta mantenibilidad puede ser el resultado de la modularidad y la extensibilidad.
Modularidad
El software resultante se compone de componentes independientes y bien definidos, lo que facilita su mantenimiento. Estos componentes pueden implementarse y probarse de forma aislada antes de integrarse para formar el sistema de software deseado. Esto permite dividir el trabajo en un proyecto de desarrollo de software.
Arriba
Cómo el consumo de recursos necesarios para cubrir los gastos generales afecta a los recursos necesarios para cumplir con los requisitos del sistema.
Actuación
El software realiza sus tareas en un plazo aceptable para el usuario y no requiere demasiada memoria.
Portabilidad
El software debe poder utilizarse en diversas condiciones y entornos.
Fiabilidad
El software es capaz de realizar la función necesaria bajo las condiciones establecidas durante un período de tiempo determinado.
Reutilización
La capacidad de utilizar algunos o todos los aspectos del software existente en otros proyectos con pocas o ninguna modificación.
Robustez
El software es capaz de funcionar bajo presión o tolerar entradas impredecibles o inválidas. Por ejemplo, puede diseñarse para ser resistente a condiciones de poca memoria.
Escalabilidad
El software se adapta bien al aumento de datos, funciones adicionales o número de usuarios. Según Marc Brooker: "un sistema es escalable en el rango donde el costo marginal de la carga de trabajo adicional es prácticamente constante". Las tecnologías sin servidor se ajustan a esta definición, pero es necesario considerar el costo total de propiedad, no solo el costo de la infraestructura. [ 11 ]
Seguridad
El software es capaz de resistir actos e influencias hostiles.
Usabilidad
La interfaz de usuario del software debe ser utilizable para su público objetivo. Los valores predeterminados de los parámetros deben elegirse de manera que sean una buena opción para la mayoría de los usuarios. [ 12 ]

Lenguaje de modelado

Un lenguaje de modelado se puede utilizar para expresar información, conocimiento o sistemas en una estructura definida por un conjunto coherente de reglas. Estas reglas se utilizan para la interpretación de los componentes dentro de la estructura. Un lenguaje de modelado puede ser gráfico o textual. Algunos ejemplos de lenguajes de modelado gráfico para el diseño de software son:

Lenguaje de descripción de arquitectura (ADL)
Un lenguaje utilizado para describir y representar la arquitectura de software de un sistema de software .
Notación de modelado de procesos de negocio (BPMN)
Un ejemplo de lenguaje de modelado de procesos .
EXPRESS y EXPRESS-G (ISO 10303-11)
Un lenguaje de modelado de datos de propósito general, estándar internacional .
Lenguaje de modelado empresarial extendido (EEML)
Se utiliza habitualmente para el modelado de procesos de negocio en varias capas.
Diagrama de flujo
Representaciones esquemáticas de algoritmos u otros procesos por etapas.
Conceptos Fundamentales de Modelado (FMC)
Un lenguaje de modelado para sistemas con uso intensivo de software.
IDEF
Una familia de lenguajes de modelado, entre los que destacan IDEF0 para el modelado funcional, IDEF1X para el modelado de información e IDEF5 para el modelado de ontologías .
Programación Estructurada de Jackson (JSP)
Un método de programación estructurada basado en correspondencias entre la estructura del flujo de datos y la estructura del programa.
LePUS3
Un lenguaje de descripción de diseño visual orientado a objetos y un lenguaje de especificación formal adecuado principalmente para modelar grandes programas orientados a objetos ( Java , C++ , C# ) y patrones de diseño .
Ejemplo de diagrama de componentes UML
Lenguaje Unificado de Modelado (UML)
Un lenguaje de modelado general para describir el software tanto estructural como conductualmente. Tiene una notación gráfica y permite la extensión con un perfil (UML) .
Aleación (lenguaje de especificación)
Lenguaje de especificación de propósito general para expresar restricciones estructurales y comportamientos complejos en un sistema de software. Proporciona un lenguaje conciso basado en lógica relacional de primer orden.
Lenguaje de modelado de sistemas (SysML)
Un lenguaje de modelado de propósito general para la ingeniería de sistemas.
Marco de modelado orientado a servicios (SOMF) [ 13 ]

Véase también

Referencias

  1. Ralph, P. y Wand, Y. (2009). Una propuesta para una definición formal del concepto de diseño. En Lyytinen, K., Loucopoulos, P., Mylopoulos, J. y Robinson, W., editores, Design Requirements Workshop (LNBIP 14), pp. 103–136. Springer-Verlag, p. 109 doi : 10.1007/978-3-540-92966-6_6 .
  2. Freeman, Peter; David Hart (2004). "Una ciencia del diseño para sistemas intensivos en software". Communications of the ACM . 47 (8): 19–21 [20]. doi : 10.1145/1012037.1012054 . S2CID 14331332 . 
  3. Ralph, P., y Wand, Y. Una propuesta para una definición formal del concepto de diseño. En Lyytinen, K., Loucopoulos, P., Mylopoulos, J., y Robinson, W., (eds.), Ingeniería de requisitos de diseño: una perspectiva de diez años: Springer-Verlag, 2009, pp. 103-136.
  4. Dijkstra, EW (1988). "Sobre la crueldad de enseñar realmente ciencias de la computación" . Recuperado el 10 de enero de 2014 .
  5. Knuth, Donald E. (1989). "Notas sobre los errores de TeX" (PDF) .
  6. 1 2 Fundamentos de la arquitectura de software: Un enfoque de ingeniería . O'Reilly Media. 2020. ISBN 978-1492043454.
  7. Davis, A: "201 Principios del Desarrollo de Software", McGraw Hill, 1995.
  8. Judith Bishop. "Patrones de diseño de C# 3.0: Aprovecha el poder de C# 3.0 para resolver problemas del mundo real" . Libros de C# de O'Reilly Media . Consultado el 15 de mayo de 2012. Si quieres acelerar el desarrollo de tus aplicaciones .NET, estás listo para los patrones de diseño de C#: métodos elegantes, aceptados y probados para abordar problemas comunes de programación.
  9. Booch, Grady; et al. (2004). Análisis y diseño orientado a objetos con aplicaciones (3.ª ed.). MA, EE. UU.: Addison Wesley. ISBN   0-201-89551-XConsultado el 30 de enero de 2015 .
  10. Suryanarayana, Girish (noviembre de 2014). Refactoring for Software Design Smells . Morgan Kaufmann. pág. 258. ISBN  978-0128013977.
  11. Creación de aplicaciones sin servidor en Knative . O'Reilly Media. ISBN 9781098142049.
  12. Carroll, John, ed. (1995). Diseño basado en escenarios: Visualizando el trabajo y la tecnología en el desarrollo de sistemas . Nueva York: John Wiley & Sons. ISBN 0471076597.
  13. Bell, Michael (2008). «Introducción al modelado orientado a servicios». Modelado orientado a servicios: análisis, diseño y arquitectura de servicios . Wiley & Sons. ISBN 978-0-470-14111-3.

^ Roger S. Pressman (2001). Ingeniería de software: un enfoque práctico . McGraw-Hill. ISBN 0-07-365578-3.