Separación de intereses - Separation of concerns

En informática , la separación de preocupaciones ( SoC ) es un principio de diseño para separar un programa informático en distintas secciones. Cada sección aborda una preocupación separada , un conjunto de información que afecta el código de un programa de computadora. Una preocupación puede ser tan general como "los detalles del hardware para una aplicación", o tan específica como "el nombre de qué clase instanciar". Un programa que encarna bien el SoC se denomina programa modular . La modularidad, y por lo tanto la separación de preocupaciones, se logra encapsulando información dentro de una sección de código que tiene una interfaz bien definida. La encapsulación es un medio para ocultar información . Los diseños en capas en los sistemas de información son otra forma de realización de la separación de preocupaciones (por ejemplo, capa de presentación, capa de lógica empresarial, capa de acceso a datos, capa de persistencia).

La separación de preocupaciones da como resultado más grados de libertad para algún aspecto del diseño, implementación o uso del programa. Entre ellos, es común una mayor libertad para simplificar y mantener el código. Cuando las preocupaciones están bien separadas, hay más oportunidades para la actualización, reutilización y desarrollo independiente del módulo. Ocultar los detalles de implementación de los módulos detrás de una interfaz permite mejorar o modificar la sección de código de una sola preocupación sin tener que conocer los detalles de otras secciones y sin tener que realizar los cambios correspondientes en esas otras secciones. Los módulos también pueden exponer diferentes versiones de una interfaz, lo que aumenta la libertad de actualizar un sistema complejo de manera gradual sin pérdida provisional de funcionalidad.

La separación de preocupaciones es una forma de abstracción . Como con la mayoría de las abstracciones, separar preocupaciones significa agregar interfaces de código adicionales, generalmente creando más código para ejecutar. Entonces, a pesar de los muchos beneficios de las preocupaciones bien separadas, a menudo existe una penalización de ejecución asociada.

Implementación

Los mecanismos de programación modular u orientada a objetos que proporciona un lenguaje de programación son mecanismos que permiten a los desarrolladores proporcionar SoC. Por ejemplo, los lenguajes de programación orientados a objetos como C # , C ++ , Delphi y Java pueden separar las preocupaciones en objetos , y los patrones de diseño arquitectónico como MVC o MVP pueden separar el contenido de la presentación y el procesamiento de datos (modelo) del contenido. El diseño orientado a servicios puede separar las preocupaciones en servicios . Los lenguajes de programación procedimentales como C y Pascal pueden separar preocupaciones en procedimientos o funciones . Los lenguajes de programación orientados a aspectos pueden separar las preocupaciones en aspectos y objetos .

La separación de preocupaciones es un principio de diseño importante también en muchas otras áreas, como la planificación urbana , la arquitectura y el diseño de información . El objetivo es comprender, diseñar y administrar de manera más eficaz sistemas interdependientes complejos, de modo que las funciones puedan reutilizarse, optimizarse independientemente de otras funciones y aislarse de la falla potencial de otras funciones.

Los ejemplos comunes incluyen separar un espacio en habitaciones, para que la actividad en una habitación no afecte a las personas en otras habitaciones y mantener la estufa en un circuito y las luces en otro, de modo que la sobrecarga de la estufa no apague las luces. El ejemplo con habitaciones muestra la encapsulación, donde la información dentro de una habitación, como qué tan desordenada está, no está disponible para las otras habitaciones, excepto a través de la interfaz, que es la puerta. El ejemplo con circuitos demuestra que la actividad dentro de un módulo, que es un circuito con consumidores de electricidad conectados, no afecta la actividad en un módulo diferente, por lo que a cada módulo no le preocupa lo que sucede en el otro.

Origen

El término separación de preocupaciones probablemente fue acuñado por Edsger W. Dijkstra en su artículo de 1974 "Sobre el papel del pensamiento científico".

Déjame intentar explicarte lo que a mi gusto es característico de todo pensamiento inteligente. Es que uno está dispuesto a estudiar en profundidad un aspecto del tema de su tema de forma aislada en aras de su propia consistencia, todo el tiempo sabiendo que uno se está ocupando sólo de uno de los aspectos. Sabemos que un programa debe ser correcto y podemos estudiarlo solo desde ese punto de vista; también sabemos que debe ser eficiente y podemos estudiar su eficiencia otro día, por así decirlo. En otro estado de ánimo, podemos preguntarnos si el programa es deseable y, de ser así, por qué. Pero no se gana nada —¡al contrario! - abordando estos diversos aspectos simultáneamente. Es lo que a veces he llamado "la separación de preocupaciones", que, aunque no sea perfectamente posible, es sin embargo la única técnica disponible para ordenar eficazmente los pensamientos de uno, que yo sepa. Esto es lo que quiero decir con "centrar la atención en algún aspecto": no significa ignorar los otros aspectos, es simplemente hacer justicia al hecho de que desde el punto de vista de este aspecto, el otro es irrelevante. Se trata de tener una mentalidad única y múltiple al mismo tiempo.

Quince años después, era evidente que el término separación de preocupaciones se estaba convirtiendo en una idea aceptada. En 1989, Chris Reade escribió un libro titulado Elementos de programación funcional que describe la separación de preocupaciones:

El programador tiene que hacer varias cosas al mismo tiempo, a saber,

  1. describir lo que se va a calcular;
  2. organizar la secuencia de cálculo en pequeños pasos;
  3. organizar la gestión de la memoria durante el cálculo.

Reade continúa diciendo,

Idealmente, el programador debería poder concentrarse en la primera de las tres tareas (describir lo que se va a calcular) sin distraerse con las otras dos, más administrativas, tareas. Claramente, la administración es importante, pero al separarla de la tarea principal, es probable que obtengamos resultados más confiables y podamos aliviar el problema de programación automatizando gran parte de la administración.

La separación de preocupaciones también tiene otras ventajas. Por ejemplo, la demostración del programa se vuelve mucho más factible cuando los detalles de la secuenciación y la gestión de la memoria están ausentes del programa. Además, las descripciones de lo que se va a calcular deben estar libres de descripciones detalladas paso a paso de cómo hacerlo, si se van a evaluar con diferentes arquitecturas de máquinas. Las secuencias de pequeños cambios en un objeto de datos guardado en una tienda pueden ser una descripción inapropiada de cómo calcular algo cuando se usa una máquina altamente paralela con miles de procesadores distribuidos por toda la máquina e instalaciones de almacenamiento locales en lugar de globales.

Automatizar los aspectos administrativos significa que el implementador del lenguaje tiene que lidiar con ellos, pero tiene muchas más oportunidades de hacer uso de mecanismos de cálculo muy diferentes con diferentes arquitecturas de máquina.

Ejemplos de

Pila de protocolos de Internet

La separación de preocupaciones es fundamental para el diseño de Internet. En Internet Protocol Suite , se han realizado grandes esfuerzos para separar las preocupaciones en capas bien definidas . Esto permite a los diseñadores de protocolos centrarse en las preocupaciones de una capa e ignorar las otras capas. El protocolo de capa de aplicación SMTP, por ejemplo, se preocupa por todos los detalles de la realización de una sesión de correo electrónico a través de un servicio de transporte confiable (generalmente TCP ), pero no le preocupa en lo más mínimo cómo el servicio de transporte hace que ese servicio sea confiable. De manera similar, TCP no se preocupa por el enrutamiento de paquetes de datos, que se maneja en la capa de Internet .

HTML, CSS, JavaScript

El lenguaje de marcado de hipertexto (HTML), las hojas de estilo en cascada (CSS) y JavaScript (JS) son lenguajes complementarios que se utilizan en el desarrollo de páginas web y sitios web. HTML se usa principalmente para la organización del contenido de la página web, CSS se usa para definir el estilo de presentación del contenido y JS define cómo el contenido interactúa y se comporta con el usuario. Históricamente, este no era el caso: antes de la introducción de CSS, HTML realizaba las dos funciones de definir la semántica y el estilo.

Programación orientada a temas

La programación orientada a temas permite abordar preocupaciones independientes como construcciones de software independientes, cada una en pie de igualdad con las demás. Cada preocupación proporciona su propia estructura de clases en la que se organizan los objetos en común, y aporta estados y métodos al resultado compuesto en el que se cruzan entre sí. Las reglas de correspondencia describen cómo las clases y los métodos en las diversas preocupaciones se relacionan entre sí en los puntos donde interactúan, lo que permite que el comportamiento compuesto de un método se derive de varias preocupaciones. La separación multidimensional de inquietudes permite manipular el análisis y la composición de inquietudes como una "matriz" multidimensional en la que cada inquietud proporciona una dimensión en la que se enumeran diferentes puntos de elección, con las celdas de la matriz ocupadas por la correspondiente artefactos de software.

Programación Orientada a Aspectos

La programación orientada a aspectos permite abordar preocupaciones transversales como preocupaciones primarias. Por ejemplo, la mayoría de los programas requieren algún tipo de seguridad y registro . La seguridad y el registro son a menudo preocupaciones secundarias, mientras que la principal preocupación suele ser el logro de los objetivos comerciales. Sin embargo, al diseñar un programa, su seguridad debe integrarse en el diseño desde el principio en lugar de tratarse como una preocupación secundaria. La aplicación posterior de la seguridad a menudo da como resultado un modelo de seguridad insuficiente que deja demasiados huecos para futuros ataques. Esto puede resolverse con programación orientada a aspectos. Por ejemplo, se puede escribir un aspecto para imponer que las llamadas a una determinada API siempre se registren, o que los errores siempre se registren cuando se lanza una excepción, independientemente de si el código de procedimiento del programa maneja la excepción o la propaga.

Niveles de análisis en inteligencia artificial

En ciencia cognitiva e inteligencia artificial , es común referirse a los niveles de análisis de David Marr . En un momento dado, un investigador puede centrarse en (1) qué necesita algún aspecto de la inteligencia para calcular, (2) qué algoritmo emplea o (3) cómo se implementa ese algoritmo en el hardware. Esta separación de preocupaciones es similar a la distinción de interfaz / implementación en la ingeniería de software y hardware.

Sistemas normalizados

En los sistemas normalizados, la separación de preocupaciones es uno de los cuatro principios rectores. Adherirse a este principio es una de las herramientas que ayuda a reducir los efectos combinatorios que, con el tiempo, se van introduciendo en el software que se mantiene. En los sistemas normalizados, la separación de preocupaciones es apoyada activamente por las herramientas.

SoC a través de clases parciales

La separación de preocupaciones se puede implementar y hacer cumplir a través de clases parciales .

SoC a través de clases parciales en Ruby

bear_hunting.rb
class Bear
  def hunt
    forest.select(&:food?)
  end
end
bear_eating.rb
class Bear
  def eat(food)
    raise "#{food} is not edible!" unless food.respond_to? :nutrition_value
    food.nutrition_value
  end
end
bear_hunger.rb
class Bear
  attr_accessor :hunger
  def monitor_hunger
    if hunger > 50
      food = hunt
      hunger -= eat(food)
    end
  end
end

Ver también

Referencias

enlaces externos