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?
IF
,WHILE
,FOR
en lugar deGOTO
. 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
).)Respuestas:
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.
fuente
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.
fuente
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.
fuente
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.
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.
fuente
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
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?
fuente
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".
fuente