El diseño de software es el proceso de conceptualizar cómo funcionará un sistema de software antes de implementarlo o modificarlo. [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 consisten tanto en documentación de diseño como en conceptos no documentados.
El proceso de diseño permite a un diseñador modelar varios aspectos de un sistema de software antes de que exista.
La creatividad, la experiencia previa, el sentido de lo que hace que un software sea "bueno" y el compromiso con la calidad son factores de éxito para un diseño competente. Sin embargo, el proceso de diseño no siempre es un procedimiento sencillo.
El modelo de diseño de software se puede comparar con un plano arquitectónico de una casa. Los planos de alto nivel representan la totalidad de la casa (por ejemplo, una representación tridimensional de la casa). Los planos de nivel inferior proporcionan una guía para construir cada detalle (por ejemplo, la instalación de plomería). De manera similar, el modelo de diseño de software proporciona una variedad de vistas de la solución de software propuesta.
Valor
La documentación de diseño de software puede revisarse o presentarse para permitir que se ajusten las restricciones, especificaciones e incluso requisitos antes de la codificación . El rediseño puede ocurrir después de una revisión de una simulación programada o un prototipo . Es posible diseñar software en el proceso de codificación, sin un plan o análisis de requisitos, [3] pero para proyectos más complejos esto es menos factible. Un diseño separado antes de la codificación permite que los diseñadores multidisciplinarios y los expertos en la materia (SMEs) colaboren con los programadores para producir software que sea útil y técnicamente sólido.
El resultado del análisis son problemas más pequeños que resolver. En cambio, el diseño se centra en las capacidades, por lo que pueden existir múltiples diseños para el mismo problema. Dependiendo del entorno, el diseño suele variar, ya sea creado a partir de marcos confiables o implementado con patrones de diseño adecuados .
A veces, el resultado de un proceso de diseño es la documentación del diseño .
Principios de diseño
Los principios básicos de diseño permiten a un ingeniero de software navegar por el proceso de diseño. Davis [4] sugiere un conjunto de principios para el diseño de software, que se han adaptado y ampliado en la siguiente lista:
El proceso de diseño no debe verse afectado por una visión de túnel. Un buen diseñador debe considerar enfoques alternativos y evaluar cada uno de ellos en función de los requisitos del problema y los recursos disponibles para realizar el trabajo.
El diseño debe poder rastrearse hasta el modelo de análisis. Debido a que un solo elemento del modelo de diseño a menudo puede rastrearse hasta múltiples requisitos, es necesario tener un medio para rastrear cómo se han satisfecho los requisitos mediante el modelo de diseño.
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 han utilizado antes. Estos patrones siempre deben elegirse como una alternativa a la reinvención. El tiempo es escaso y los recursos limitados; el tiempo de diseño debe invertirse en representar ideas (realmente nuevas) mediante la integración de patrones que ya existen (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 debe, 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 parece totalmente coherente. Para lograr este resultado, se deben definir reglas de estilo y formato para un equipo de diseño antes de comenzar el trabajo de diseño. Un diseño es integrado si se tiene cuidado al definir las interfaces entre los componentes del diseño.
El diseño debe estructurarse para adaptarse a los cambios. Los conceptos de diseño que se analizan en la siguiente sección permiten que un diseño logre este principio.
El diseño debe estructurarse para degradarse suavemente, incluso cuando se encuentren datos, eventos o condiciones operativas aberrantes. Un software bien diseñado nunca debe "fallar"; debe estar diseñado para adaptarse a circunstancias inusuales y, si debe finalizar el procesamiento, debe hacerlo de manera elegante.
El diseño no es codificación, la codificació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 más alto que el 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.
La calidad del diseño debe evaluarse durante su creación, no después. Hay una variedad de conceptos y medidas de diseño disponibles para ayudar al diseñador a evaluar la calidad durante todo el proceso de desarrollo.
El diseño debe revisarse para minimizar los errores conceptuales (semánticos). A veces, existe una tendencia a centrarse en los detalles cuando se revisa el diseño, pasando por alto lo esencial. Un equipo de diseño debe asegurarse de que se hayan abordado los principales elementos conceptuales del diseño (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. Se ha desarrollado un conjunto de conceptos de diseño que incluyen:
Abstracción : La abstracción es el proceso o resultado de la generalización mediante la reducción del contenido de información de un concepto o un fenómeno observable, generalmente para retener solo la información que es relevante para un propósito particular. Es un acto de representar características esenciales sin incluir los detalles o explicaciones de fondo.
Refinamiento - Es el proceso de elaboración. Se desarrolla una jerarquía descomponiendo un enunciado macroscópico de función de manera gradual hasta llegar a los enunciados 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.
Modularidad : La arquitectura del software se divide en componentes llamados módulos.
Arquitectura de software : se refiere a la estructura general del software y las formas en que dicha estructura proporciona integridad conceptual a un sistema. Una buena arquitectura de software producirá un buen retorno de la inversión con respecto al resultado deseado del proyecto, por ejemplo, en términos de rendimiento, calidad, cronograma y costo.
Jerarquía de control: Estructura de programa que representa la organización de un componente del programa e implica una jerarquía de control.
Particiones estructurales: 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. Las particiones verticales sugieren que el control y el trabajo deben distribuirse de arriba hacia abajo en la estructura del programa.
Estructura de datos : es una representación de la relación lógica entre elementos individuales de datos.
Procedimiento de Software - Se centra en el procesamiento de cada módulo individualmente.
Ocultación de información : los módulos deben especificarse y diseñarse de modo que la información contenida en un módulo sea inaccesible para otros módulos que no necesitan dicha información.
En su modelo de objetos, Grady Booch menciona la abstracción , la encapsulación , la modularización y la jerarquía como principios fundamentales del diseño de software. [5] El acrónimo PHAME (Principios de jerarquía, abstracción, modularización y encapsulación) se utiliza a veces para referirse a estos cuatro principios fundamentales. [6]
Consideraciones de diseño
Hay muchos aspectos que se deben tener en cuenta en el diseño de un software. La importancia de cada consideración debe reflejar los objetivos y expectativas que se pretenden cumplir con el software. Algunos de estos aspectos son:
Compatibilidad: el software puede funcionar con otros productos que están diseñados para la interoperabilidad con otro producto. Por ejemplo, un software puede ser compatible con versiones anteriores de sí mismo.
Extensibilidad : se pueden agregar nuevas capacidades al software sin realizar cambios importantes en la arquitectura subyacente.
Modularidad : el software resultante consta de componentes independientes bien definidos, lo que permite una mejor capacidad de mantenimiento. Los componentes se pueden implementar y probar de forma aislada antes de integrarlos para formar el sistema de software deseado. Esto permite dividir el trabajo en un proyecto de desarrollo de software.
Tolerancia a fallos : el software es resistente y capaz de recuperarse ante fallas de los componentes.
Mantenibilidad : medida de la facilidad con la que se pueden corregir errores o realizar modificaciones funcionales. Una alta capacidad de mantenimiento puede ser el resultado de la modularidad y la extensibilidad.
Confiabilidad ( durabilidad del software ): el software es capaz de realizar una función requerida bajo condiciones establecidas durante un período de tiempo específico.
Reutilización : la capacidad de utilizar algunos o todos los aspectos del software preexistente en otros proyectos con poca o ninguna modificación.
Robustez : el software puede funcionar bajo presión o tolerar entradas impredecibles o no válidas. Por ejemplo, puede diseñarse con resiliencia a condiciones de poca memoria.
Seguridad : El software es capaz de soportar y resistir actos e influencias hostiles.
Usabilidad : la interfaz de usuario del software debe ser utilizable por el usuario o público al que va dirigido. Los valores predeterminados de los parámetros deben elegirse de manera que sean una buena opción para la mayoría de los usuarios. [7]
Rendimiento : el software realiza sus tareas dentro de un período de tiempo aceptable para el usuario y no requiere demasiada memoria.
Portabilidad : el software debe poder utilizarse en distintas condiciones y entornos.
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 en el que el costo marginal de la carga de trabajo adicional es casi 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. [8]
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:
IDEF es una familia de lenguajes de modelado, entre los que se incluyen IDEF0 para modelado funcional, IDEF1X para modelado de información e IDEF5 para modelado de ontologías .
Jackson Structured Programming (JSP) es un método de programación estructurada basado en correspondencias entre la estructura del flujo de datos y la estructura del programa.
El lenguaje de modelado unificado (UML) es un lenguaje de modelado general para describir el software tanto desde el punto de vista estructural como del comportamiento. Tiene una notación gráfica y permite la extensión con un perfil (UML) .
Alloy (lenguaje de especificación) es un 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.
Un diseñador de software puede identificar un aspecto de diseño que otros han visitado y quizás incluso resuelto en el pasado. Una plantilla o patrón que describe una solución a un problema común se conoce como patrón de diseño . La reutilización de dichos patrones puede aumentar la velocidad del desarrollo de software. [10]
Código como diseño
La dificultad de utilizar el término "diseño" en relación con el software es que, en cierto sentido, el código fuente de un programa es el diseño del programa que produce. En la medida en que esto sea cierto, "diseño de software" se refiere al diseño del diseño. Edsger W. Dijkstra se refirió a esta superposición de niveles semánticos como la "novedad radical" de la programación informática, [11] 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 ideas sobre cómo podrían mejorarse las especificaciones originales. [12]
Véase también
Wikimedia Commons tiene medios relacionados con Diseño de software .
^ 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), págs. 103-136. Springer-Verlag, pág. 109 doi :10.1007/978-3-540-92966-6_6.
^ Freeman, Peter; David Hart (2004). "Una ciencia del diseño para sistemas intensivos en software". Comunicaciones de la ACM . 47 (8): 19–21 [20]. doi :10.1145/1012037.1012054. S2CID 14331332.
^ 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, págs. 103-136
^ Davis, A: "201 Principios de desarrollo de software", McGraw Hill, 1995.
^ Booch, Grady; et al. (2004). Análisis y diseño orientado a objetos con aplicaciones (3.ª ed.). MA, EE. UU.: Addison Wesley. ISBN0-201-89551-X. Recuperado el 30 de enero de 2015 .
^ Suryanarayana, Girish (noviembre de 2014). Refactorización para el diseño de software . Morgan Kaufmann. pág. 258. ISBN978-0128013977.
^ Carroll, John, ed. (1995). Diseño basado en escenarios: visualización del trabajo y la tecnología en el desarrollo de sistemas . Nueva York: John Wiley & Sons. ISBN0471076597.
^ Creación de aplicaciones sin servidor en Knative . O'Reilly Media. ISBN9781098142049.
^ Bell, Michael (2008). "Introducción al modelado orientado a servicios". Modelado orientado a servicios: análisis, diseño y arquitectura de servicios . Wiley & Sons. ISBN978-0-470-14111-3.
^ Judith Bishop. "Patrones de diseño de C# 3.0: use 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 desea acelerar el desarrollo de sus aplicaciones .NET, está listo para los patrones de diseño de C#: formas elegantes, aceptadas y probadas de abordar problemas de programación comunes.
^ Dijkstra, EW (1988). "Sobre la crueldad de enseñar realmente ciencias de la computación" . Consultado el 10 de enero de 2014 .
^ Knuth, Donald E. (1989). "Notas sobre los errores de TeX" (PDF) .
^ Roger S. Pressman (2001). Ingeniería de software: un enfoque práctico . McGraw-Hill. ISBN0-07-365578-3.