¿Dijkstra tenía la intención de modularizar el código cuando escribió sobre la separación de preocupaciones?

9

Primero, leí un extracto del artículo de 1974 de Edsger W. Dijkstra "Sobre el papel del pensamiento científico":

Permíteme explicarte, lo que a mi gusto es característico de todo pensamiento inteligente. Es decir, que uno está dispuesto a estudiar en profundidad un aspecto del tema de forma aislada por el bien de su propia consistencia, todo el tiempo sabiendo que se está ocupando solo en uno de los aspectos. Sabemos que un programa debe ser correcto y podemos estudiarlo solo desde ese punto de vista; También sabemos que debería ser eficiente y podemos estudiar su eficiencia en otro día, por así decirlo. En otro estado de ánimo, podemos preguntarnos si, y si es así: por qué, el programa es deseable. Pero no se gana nada, por el 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 la única técnica disponible para ordenar eficazmente los pensamientos, que yo sepa. Esto es lo que quiero decir con "centrar la atención en algún aspecto": no significa ignorar los otros aspectos, solo hace justicia al hecho de que, desde el punto de vista de este aspecto, el otro es irrelevante. Se trata de mentalidad de una y varias pistas simultáneamente.

Veo que la separación moderna de preocupaciones habla de modularizar su código. Sin embargo, al leer la cita anterior, entiendo esto como enfocar tu mente en una tarea en particular a la vez, sin enfocarme en otros aspectos. Esto no significa necesariamente que el código deba separarse en fragmentos modulares.

Es decir, digamos que hay un código frente a usted que en un archivo tiene los conceptos de vista, repositorio, controlador, manejo de eventos, fábrica, etc., todo en un solo archivo.

Para un breve ejemplo, aquí hay un código que tiene acceso a datos y vista (salida):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

Usando OO moderno, podría colocar el acceso a datos en su propio archivo usando el patrón de Repositorio, el código de Vista puede ir a su propia plantilla de archivo, y puedo conectarlos juntos para comunicarse a través de un controlador (o un Controlador de Acción o Solicitud), y puedo agregue una fábrica para crear y conectar varias dependencias. Y puedo tener un archivo de configuración que defina esas fábricas. Seguramente está a un paso de un solo archivo de todo.

Mi pregunta sobre la separación de preocupaciones es así: leyendo la cita de Dijkstra, tuve la idea de que tal vez no necesariamente significaba que la separación de preocupaciones era "separación modular de código (en archivos o sus propias funciones / métodos / etc.)", y que quería decir más para enfocar la mente en un aspecto del programa, sin agobiarte enfocándote en otros aspectos importantes pero aún no considerados, independientemente de si están físicamente separados en el código o no.

¿Por qué entonces nos estamos abrumando con la separación física del código modular y los patrones de diseño? ¿No será suficiente enfocarse solo en un aspecto, independientemente de cómo esté estructurado su código?

No estoy hablando de escribir el código de espagueti más horrible y luego solo considerar un aspecto del mismo, eso probablemente sería una carga. Pero al final, a lo que me dirijo es, ¿por qué realizar la separación del código físico, por qué dividir el código en archivos o fragmentos (métodos) separados, cuando no es necesario enfocarse mentalmente en un aspecto?

¿Debería la separación de preocupaciones seguir siendo un ejercicio mental, más que físico?
En otras palabras, ¿debería haber una desconexión entre los aspectos mentales (centrarse en) y físicos (código en papel) de la programación?

Dennis
fuente
55
Estoy bastante seguro de que en 1974, él solo veía la programación modular como algo obvio, y es por eso que no lo discutió explícitamente en ese documento. El documento de Parnas sobre cómo modularizar fue en 1972, y para ese momento si modularizar ya no era una pregunta. De hecho, lo que usted describe no es ni siquiera una programación modular, es una programación estructurada , que Dijkstra argumentó firmemente a favor ya en 1968 en su clásico artículo "Go To Considered Harmful".
Jörg W Mittag
De acuerdo, tal vez pueda entender la "separación de preocupaciones" más como un ejercicio de enfoque mental, y la modularización como una forma de encapsular un aspecto del código en papel. Sin embargo, ahora veo la separación de las preocupaciones y la modularización más como conceptos separados.
Dennis
@ JörgWMittag, ¿puede definir la distinción entre programación estructurada y modular? Algunos enlaces en google sugieren que son lo mismo.
Dennis
Estructurado = IF, WHILE, FORen lugar de GOTO. Modular = módulos con una API pública bien definida estrictamente separada de una implementación interna oculta y representación. (Por ejemplo, Modula, Mesa, Modula-2, Modula-3, luego dialectos Pascal ( UNIT).)
Jörg W Mittag

Respuestas:

2

Dijkstra está haciendo una declaración explícita sobre cómo pensar. La modularización de programas (y procesos), y su conveniencia, es quizás el resultado de ese pensamiento, pero el punto clave que está haciendo es cómo evaluar un problema. El programa suele ser la solución a un problema, y ​​al abogar por una "separación de preocupaciones", está ofreciendo sabios consejos. El mejor ejemplo de esto es quizás la "optimización". La broma fue: "Cuando se planifica optimizar un programa, su primera estrategia debería ser: no". En otras palabras, desea centrarse primero en hacer que el programa sea correcto. Hacer que sea rápido y elegante es una preocupación que debe separarse, pero tampoco eliminarse por completo.

MCL
fuente
14

La separación de las preocupaciones es una forma abstracta de pensar que consiste en considerar por separado las cosas que no tienen que estar relacionadas.

La modularización (que separa un grupo de funciones no relacionadas en módulos), la encapsulación (que oculta los detalles internos de los módulos) y la abstracción (que separa lo general de lo específico y la idea de su implementación) son todos medios para implementar esta forma de pensar en el dominio de diseño de software.

Christophe
fuente
9

Sugeriría que, si bien el documento es de interés histórico, lo que Dijkstra quiso decir con el término "separación de preocupaciones" hace más de 40 años no es particularmente relevante hoy en día. Hoy en día se usa ampliamente en referencia a la modulización.

Existe una gran cantidad de evidencia de que la modulización es enormemente beneficiosa y que esos beneficios superan con creces las "cargas" que nos impone. Lo que sea que Dijkstra quiso decir en ese momento, no cambia el hecho de que pequeños fragmentos de código, cada uno enfocado en una sola cosa, conduce a un código que es más fácil de escribir, leer, comprender, mantener y probar.

David Arno
fuente
55
Creo que debe tenerse en cuenta que gran parte del pensamiento moderno sobre la separación de preocupaciones provino de los primeros documentos que finalmente generaron la programación orientada a aspectos de IBM. Creo que los documentos iniciales (finales de los 90 y principios de los 2000) son la mayor influencia allí. Ha pasado un tiempo y los sitios web han cambiado. No estoy seguro si puedo encontrarlos de nuevo.
Berin Loritsch
2
La parte difícil es tratar de definir qué significa "una cosa". Sin eso, la idea es inútil en términos de escritura práctica de códigos, y equivocarse tiene efectos perjudiciales inmediatos sobre la dificultad de escribir, leer, comprender, mantener y probar el código.
jpmc26
1
Realmente nos ayudaría a entender su posición si (a) explicara lo que cree que Dijkstra quiso decir con "separación de preocupaciones" y (b) explicaría POR QUÉ cree que lo que quiso decir ya no es relevante.
John R. Strohm
2

Puedo darle un ejemplo personal de separación de preocupaciones que creo que es comparable a los conceptos de Dijkstra. Cuando analizo un tema en particular en el software, construyo tres vistas.

  1. Primero considero los datos. Los datos representan los predicados lógicos del problema. Las clases se construyen para entidades abstractas en el mundo real, siendo sus atributos los parámetros de la abstracción. Las asociaciones entre clases representan asignaciones funcionales entre las instancias de clase. No hay código involucrado en el pensamiento en este momento y no hay noción de ningún procesamiento. Solo una visión estática de la lógica involucrada en el tema.
  2. Segundo, considero la dinámica. Cualquier clase que tenga un ciclo de vida no trivial se modela como una máquina de estados finitos. Esto implica consideraciones de secuencia de ejecución y sincronización. Nuevamente, no hay código que solo resuelva cómo interactúan y se secuencian las cosas.
  3. Tercero, considero el procesamiento. Aquí, el trabajo algorítmico real que debe hacerse en transiciones de estado o en otras operaciones sincrónicas.

Al final, se obtiene una vista de tres facetas del tema que luego se puede formular como código en cualquier agrupación que sea conveniente para el código en sí y su mantenimiento. Las tres facetas no son solo un ejercicio mental. Produzco descripciones escritas de todas las facetas. ¿Por qué? Porque si el tema es lo suficientemente grande, no puedo mantener ni siquiera una faceta completa en la memoria a corto plazo. Si el tema es pequeño, casi cualquier enfoque funcionará porque puedes tenerlo todo en tu cabeza.

La motivación para separar las preocupaciones es acomodar las limitaciones de memoria a corto plazo de los humanos. Simplemente no podemos cargar todo en nuestras cabezas a la vez, aunque los programadores de computadoras tienden a ser más capaces que la mayoría de las otras personas en la cantidad de conceptos que pueden manipular en su memoria a corto plazo. Para ser efectivo, las preocupaciones de separación deben ser sistemáticamenteexcluir uno o más aspectos de un problema para enfocarse en algún otro aspecto particular. Por supuesto, excluir un aspecto no hace que desaparezca de consideración. Debe haber un medio para combinar todos los aspectos problemáticos para lograr una solución. La experiencia muestra que a menudo el resultado final de la separación y la recombinación produce una solución más comprensible que un solo salto gigante en el que muchos aspectos podrían mezclarse. Este es particularmente el caso cuando el tamaño del problema es grande o complejo.

andy mango
fuente
1

La separación de preocupaciones es un concepto lógico que se propagará en su modelo de organización de código sin importar cómo lo implemente. Es cierto que un archivo de código es solo un detalle técnico, una forma de mantener su software manejable. Un solo archivo con un buen editor que permita colapsar una expansión de regiones también podría funcionar para usted (por un tiempo). O una base de datos relacional que almacena clases y métodos de una manera padre-hijo en tablas separadas podría funcionar como un medio de almacenamiento. Pero los archivos de texto son difíciles de superar en un mundo donde el código fuente debe ser

  • portátil
  • accesible por muchas herramientas externas diferentes
  • accesible por múltiples programadores
  • versionable y comparable
  • escalar bien con sistemas operativos que resultan ser muy buenos en el manejo de archivos

La conclusión es que los humanos no somos muy buenos para pensar o tratar diferentes cosas a la vez. Por lo tanto, necesitamos un modelo que permita pensar y trabajar en una cosa a la vez sin el peligro de arruinar otra parte que no estamos considerando en ese momento. Por lo tanto, construimos, colocando un ladrillo a la vez, asegurándonos de que los ladrillos que colocamos antes no interfieran con los ladrillos colocados más tarde. Y si queremos cambiar un ladrillo más tarde, las cosas no deben colapsar. Ese es un modelo que funciona para nuestras mentes de una sola pista.

No es así como crecen los hongos o las algas ... ¿Cómo es eso para un hecho humillante?

Martin Maat
fuente
-1

Sin embargo, creo que la respuesta específica a la cita de Dijkstra se ha abordado, ya que usted dice "Usando OO moderno, podría colocar el acceso a datos en su propio archivo" y pregunta "¿Debería la separación de preocupaciones seguir siendo un ejercicio mental, en lugar de físico?" permítanme llamar su atención sobre dónde nos dirigen los directores de OO modernos.

Uno debe seguir los principios SOLIDOS en el desarrollo usando OO. Aquí hay un buen enlace para ellos, pero, el TLDR sobre "separación de preocupaciones" se encuentra principalmente en S en SÓLIDO: El Principio de Responsabilidad Única o SRP.

Esto, definitivamente, es un ejercicio físico, no mental. Para su ejemplo específico, MVC (o sus hermanos MVVM y MVP) le ordena a uno que separe físicamente los conciertos de Model, View y Controller / Presenter / ViewModel en archivos separados. He visto algunas implementaciones de MVVM donde se implementan en ensamblajes separados para restringir aún más la tendencia de uno a "mezclar conceptos".

Pero. Va más allá del simple "esta es una vista y este es un modelo", si sigue la opinión del tío Bob sobre esto.

También se debe considerar la fuente de los requisitos para cualquier elemento OO en particular. Si está mezclando, digamos, lo que quiere el Cliente con lo que quiere el Personal de Operaciones, también está violando el SRP. O, para decirlo como lo hace el tío Bob: una clase debe tener una y solo una razón para cambiar.

Le recomiendo que investigue más a fondo utilizando los enlaces suministrados o realice una búsqueda en la web de "principios sólidos".

Azul Reginald
fuente
No. Los principios SÓLIDOS están tan desconectados de la realidad de escribir código (= filosófico) que solo pueden entenderse de una manera remotamente útil una vez que ya sabe cómo escribir un buen código, en cuyo punto son redundantes en el mejor de los casos. Usarlos como principios rectores sin tener experiencia y habilidad produce un código extremadamente pobre.
jpmc26