¿Puede ser mala la abstracción en exceso?

43

Como programadores, creo que nuestro objetivo es proporcionar buenas abstracciones sobre el modelo de dominio y la lógica empresarial dados. ¿Pero dónde debería detenerse esta abstracción? Cómo hacer el equilibrio entre la abstracción y todos sus beneficios (flexibilidad, facilidad de cambio, etc.) y la facilidad de entender el código y todos sus beneficios.

Creo que tiendo a escribir código demasiado abstracto y no sé qué tan bueno es; A menudo tiendo a escribirlo como si fuera una especie de micro-marco, que consta de dos partes:

  1. Micro-módulos que están conectados en el micro-marco: estos módulos son fáciles de entender, desarrollar y mantener como unidades individuales. Básicamente, este código representa el código que realmente hace las cosas funcionales, descritas en los requisitos.
  2. Código de conexión; Ahora aquí creo que está el problema. Este código tiende a ser complicado porque a veces es muy abstracto y es difícil de entender al principio; esto se debe al hecho de que es solo una abstracción pura, la base en la realidad y la lógica de negocios se realiza en el código presentado 1; por este motivo, no se espera que este código se modifique una vez probado.

¿Es este un buen enfoque en la programación? ¿Que, tener código cambiante muy fragmentado en muchos módulos y muy fácil de entender y código no cambiante muy complejo desde la abstracción POV? Si todo el código fuera uniformemente complejo (es decir, el código 1 es más complejo e interconectado y el código 2 más sencillo) para que cualquiera que lo busque pueda entenderlo en un tiempo razonable, pero el cambio es costoso o la solución presentada es buena, donde El "cambio de código" es muy fácil de entender, depurar, cambiar y el "código de enlace" es algo difícil.

Nota: esto no se trata de la legibilidad del código! Tanto el código 1 como el 2 son legibles, pero el código 2 viene con abstracciones más complejas, mientras que el código 1 viene con abstracciones simples.

    
pregunta m3th0dman 23.06.2013 - 23:09

4 respuestas

73

Las primeras palabras de TC ++ PL4:

Todos los problemas en informática Puede ser resuelto por otro nivel de direccionamiento indirecto, a excepción del problema de demasiadas capas de direccionamiento indirecto. - David J. Wheeler

(David Wheeler fue mi asesor de tesis. La cita sin la última línea importante a veces se llama "La primera ley de la informática"))

    
respondido por el Bjarne 24.06.2013 - 00:54
29

Sí, definitivamente. La cosa es que ninguna abstracción es perfecta. Todos los detalles de la capa en la que se encuentran las abstracciones están ahí por una razón, y puede simplificar muchas cosas, pero si esa complejidad no fuera necesaria en algún momento, probablemente no estaría ahí en primer lugar. Y eso significa que en algún momento, cada abstracción se filtrará de alguna manera.

Y ahí es donde radica el problema real. Cuando las abstracciones fallan, cuantas más capas hay entre el código que escribiste y lo que realmente está sucediendo, más difícil es resolver el problema y solucionarlo, porque hay más lugares donde podría estar el problema. Y mientras más capas haya, más tienes que saber para rastrearlas.

    
respondido por el Mason Wheeler 23.06.2013 - 23:19
13

Sí, absolutamente.

La analogía que me gusta usar para explicar la programación es la de un Tailor. Al hacer un traje, un buen Tailor siempre dejará una pequeña cantidad de tejido en lugares estratégicos dentro de la prenda para permitir que la prenda se pueda llevar dentro o fuera, sin cambiar su forma o estructura general.

El buen sastre no deja resmas de tela en cada costura, en caso de que crezca un tercer brazo o quede embarazada. Demasiado material en los lugares equivocados resultará en una prenda mal ajustada y de mal uso, la tela adicional simplemente se interpone en el camino del uso normal. La tela es muy pequeña y la prenda es propensa a las lágrimas y no se podrá alterar para hacer frente a cambios menores en el físico de su portador, lo que afectará la forma en que se sienta la prenda.

Tal vez algún día, nuestro buen sastre tendrá la tarea de hacer un vestido tan ajustado que tenga que coser su ropa. Y tal vez se le pide a nuestra Good Tailor que haga ropa de maternidad, donde el estilo y el ajuste son los siguientes a la comodidad y la capacidad de expansión. Pero antes de emprender cualquiera de esos trabajos especiales, un buen Tailor sería lo suficientemente inteligente como para que todos estén conscientes de los compromisos que se están haciendo para alcanzar esos objetivos.

A veces, estos compromisos son el camino correcto a seguir, y las personas están dispuestas a aceptar sus consecuencias. Pero en la mayoría de los casos, el enfoque de dejar un poco donde sea más importante será mayor que cualquier beneficio percibido.

Entonces, relacionando esto de nuevo con la abstracción. Es absolutamente posible tener demasiadas capas de abstracción, al igual que es posible tener demasiado poco. El verdadero arte del programador, como nuestros amigos sastres, es dejar un poco de lo que más cuenta.

Volviendo al tema.

El problema con el código generalmente no es la abstracción, sino las dependencias. Como has señalado, es el código que conecta los objetos discretos que es un problema, porque hay una dependencia implícita entre ellos. En algún punto, la comunicación entre cosas solo necesita ser concreta, pero juzgar dónde se encuentra ese punto generalmente requiere algunas conjeturas.

Todo lo que se dice "micro" suele ser una indicación de que has sobregranulizado el diseño de tus objetos y que probablemente estés utilizando Type como sinónimo de lo que debería ser Data . Tener menos cosas también significa menos dependencias necesarias para comunicarse entre ellas.

Por esta razón, soy un gran fanático de los mensajes asíncronos entre sistemas. Terminas con dos sistemas dependientes del mensaje , en lugar de uno con el otro. Dándole un acoplamiento menos apretado entre los sistemas de comunicación. En ese momento, si necesita tener una dependencia entre los sistemas, debe considerar si tiene los bits que son dependientes en el lugar (s) correcto (s). Y es a menudo el caso de que no.

Finalmente, el código complicado va a ser complicado. A menudo no hay manera de evitar eso. Pero el código que tiene menos dependencias es mucho más fácil de entender que uno que se basa en varios estados externos.

    
respondido por el Matt D 24.06.2013 - 11:41
12
  

Creo que nuestro objetivo es proporcionar buenas abstracciones sobre el modelo de dominio y la lógica empresarial dados.

Tengo una visión diferente: nuestro objetivo es resolver un problema de negocios. Las abstracciones son solo una técnica para organizar una solución. Otra respuesta utiliza la analogía de un sastre confeccionando ropa. Tengo otra analogía en la que me gusta pensar: un esqueleto. El código es como un esqueleto, y las abstracciones son las articulaciones entre los huesos. Si no tiene articulaciones, simplemente termina con un solo hueso que no se puede mover en absoluto y es inútil. Pero si tienes demasiadas articulaciones, terminas con una pila de gelatina descuidada que no puede soportar por sí sola. El truco es encontrar el equilibrio adecuado: suficientes juntas para permitir el movimiento, pero no tanto que no haya una forma o estructura definida real.

    
respondido por el Jordan Lev 24.06.2013 - 15:06

Lea otras preguntas en las etiquetas