2010-04-19 14 views
59

En un programa orientado a objetos: ¿Cuánta abstracción es demasiado? ¿Cuánto es justo?¿Cuánta abstracción es demasiado?

Siempre he sido un tipo loco y perno. Entendí el concepto detrás de altos niveles de encapsulación y abstracción, pero siempre sentí instintivamente que agregar demasiado confundiría el programa.

Siempre traté de fotografiar para una cantidad de abstracción que no dejaba clases o capas vacías. Y en caso de duda, en lugar de agregar una nueva capa a la jerarquía, trataría de encajar algo en las capas existentes.

Sin embargo, recientemente me he encontrado con sistemas más abstractos. Sistemas en los que todo lo que podría requerir una representación más adelante en la jerarquía obtiene uno por adelantado. Esto lleva a muchas capas vacías, lo que al principio parece un mal diseño. Sin embargo, pensándolo bien, me he dado cuenta de que dejar esas capas vacías te da más lugares para engancharte en el futuro sin mucha refactorización. Le deja una mayor capacidad para agregar una nueva funcionalidad sobre la anterior sin hacer casi tanto trabajo para ajustar la anterior.

Los dos riesgos de esto parecen ser que podría obtener las capas que necesita incorrectas. En este caso, uno terminaría necesitando una refactorización sustancial para extender el código y aún tendría toneladas de capas nunca usadas. Pero dependiendo de cuánto tiempo dediques a las abstracciones iniciales, la posibilidad de arruinarlo y el tiempo que podrías ahorrar más adelante si lo haces bien, puede que valga la pena intentarlo.

El otro riesgo que se me ocurre es el riesgo de sobrepasarlo y no necesitar todas las capas adicionales. ¿Pero eso es realmente tan malo? ¿Son las capas de clase extra realmente tan caras que es una gran pérdida si nunca se usan? El mayor gasto y pérdida aquí sería el tiempo que se pierde en la delantera al aparecer las capas. Pero gran parte de ese tiempo todavía podría guardarse más adelante cuando se pueda trabajar con el código abstraído en lugar de con un código de bajo nivel.

Entonces, ¿cuándo es demasiado? ¿En qué punto las capas vacías y las abstracciones adicionales "podrían necesitar" se vuelven excesivas? ¿Qué tan pequeño es muy poco? ¿Dónde está el punto dulce?

¿Existe alguna regla de oro confiable que hayas encontrado en el transcurso de tu carrera que te ayude a juzgar la cantidad de abstracción necesaria?

+6

¿Por cuánto tiempo es un pedazo de cuerda ??? ;) – Goz

+2

Debe ser CW en mi humilde opinión, ya que no tiene ** una ** respuesta –

+0

@Binary Worrier Hecho. –

Respuesta

16

Entonces, ¿cuándo es demasiado? ¿En qué punto las capas vacías y extra "podría necesitar" las abstracciones se vuelven excesivas? ¿Qué tan pequeño es demasiado poco? ¿Dónde está el punto dulce ?

No creo que haya una respuesta definitiva a estas preguntas. Se necesita experiencia para desarrollar una sensación de lo que es "demasiado" y "muy poco". Tal vez el uso de algunas herramientas de control de calidad o métricas puede ayudar, pero es difícil generalizar. Depende principalmente de cada caso.

Éstos son algunos enlaces que pueden inspiran en la búsqueda de respuestas:

Desarrollo se trata de encontrar la el equilibrio correcto entre las diversas tensio ns que están presentes en cualquier esfuerzo de ingeniería de software.

+6

+1 Cada vez que esté considerando agregar una capa de abstracción, considere los beneficios. No tiene sentido la abstracción solo por abstracciones. – CiscoIPPhone

+1

Este es uno muy popular sobre los riesgos de hacer que los marcos sean demasiado genéricos. ¡Cosas graciosas! http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12 –

2

La realidad es que depende de qué tan bien pueda mirar hacia el futuro. Desea planificar los cambios que puede prever sin crear demasiadas capas adicionales. Si tiene un diseño que transfiere datos entre sistemas, proceda y cree una interfaz y use la implementación planificada como la predeterminada. Por ejemplo, usa FTP para mover archivos pero sabe que el estándar estará basado en mensajes (o lo que sea) el próximo año.

En cuanto a las capas dentro del diseño, a veces las capas agregadas hacen que sea más fácil escribir clases más pequeñas. Está bien agregar capas conceptuales si significa que las clases concretas se vuelven sencillas.

6

En pocas palabras, hay demasiada abstracción si el código es difícil de entender.

Esto no quiere decir que deba codificar todo, porque es el código más fácil de escribir y leer.

La prueba más fácil es dejarlo de lado por unos días, volver a levantarlo y pregúntese: ¿tiene sentido esto? Un mejor enfoque es dárselo a otra persona, y ver si puede entenderlo o no.

+2

"Hay demasiada abstracción si el código es difícil de entender" ¿para quién entender? Empecé a trabajar en bases de código terriblemente complicadas, luego, después de un par de meses/años, puedo encontrar fácilmente mi camino. Además, he trabajado con material codificado que era imposible de entender sin insertar un par de abstracciones significativas. –

+1

Lo que quiero decir es que si el código es difícil debido a la abstracción, entonces hay demasiado. No digo que el código sin abstracción sea difícil de leer, pero debería poder ver el código y decir: "Ok, el punto A va al punto B. Eso tiene sentido". – kemiller2002

+0

Estoy de acuerdo con Kevin. Por ejemplo, a veces creo un script de shell para hacer un trabajo repetitivo, pero luego olvido cómo funciona EXACTAMENTE el script, así que acabo utilizando los comandos subyacentes. Por ejemplo, con 'du' scripts: ¿en qué directorio debo estar para ejecutar el script? ¿El archivo de salida se colocará en el directorio actual? ¿El script es asíncrono o está bloqueando? (El script exacto que tengo, llamado disk_usage es básicamente "nohup du> disk_usage_recursive.txt &" pero termino simplemente escribiendo este comando de todos los tipos). –

0

Ver el artículo (6a) de RFC 1925 y saber que es cierto. Los únicos problemas que no puede corregir al agregar capas de abstracción son los causados ​​por tener demasiadas capas de abstracción. (En particular, cada pieza de abstracción hace que todo sea más difícil de entender.)

9

En teoría, debería ser una cuestión de simple matemática utilizando sólo tres variables (bastante simples):

  • S = ahorro de uso
  • C = costo de las abstracciones adicionales
  • P = probabilidad de uso

Si S * P> C, entonces el código es bueno. Si S * P < C, entonces es malo.

La razón que es puramente teórica, sin embargo, es que generalmente no puede adivinar la probabilidad de uso o los ahorros que obtendrá al usarla. Peor aún, no puede adivinar o, por lo general, incluso medir el costo de su presencia.

Al menos algunas personas han llegado a una conclusión a partir de esto. En TDD, el mantra estándar es "no lo vas a necesitar" (YAGNI). En pocas palabras, cualquier cosa que no contribuya directamente con el código que cumpla con sus requisitos actuales se considera algo malo. En esencia, han llegado a la conclusión de que la probabilidad de uso es tan baja, que la inclusión de dicho código adicional es nunca justificada.

Parte de esto vuelve al desarrollo de "abajo hacia arriba" frente a "arriba hacia abajo". Tiendo a pensar en el desarrollo de abajo hacia arriba como "desarrollo de la biblioteca" - es decir en lugar de desarrollar una aplicación específica, realmente está desarrollando bibliotecas para el tipo de cosas que necesitará en la aplicación. El pensamiento es que con una biblioteca lo suficientemente buena, puedes desarrollar casi cualquier aplicación de ese tipo general con relativa facilidad.

Un poco también depende del tamaño del proyecto.Los grandes proyectos que permanecen en uso durante décadas justifican una inversión mucho más a largo plazo que los proyectos más pequeños que se descartan y se reemplazan mucho más rápidamente. Esto tiene análogos obvios en la vida real también. No se preocupe tanto por el ajuste, el acabado o la mano de obra en una afeitadora desechable que va a tirar en menos de una semana como lo hace en un auto nuevo que va a utilizar en los próximos años. .

2

Cada abstracción que no se utiliza realmente es demasiado. Cuanto más simple es un sistema, más fácil es cambiarlo. Las capas de abstracción casi siempre hacen que los sistemas sean más complicados.

OTOH, es ciertamente posible programar un lío complejo e inmanejable sin ningún tipo de abstracción, y algunas veces, las capas de abstracción "estandarizadas" pueden ayudar a estructurar un sistema mejor de lo que la mayoría de la gente podría hacer por sí misma.

20

¿Qué tan pequeño es demasiado pequeño?

Cuando trabajas con elementos de "bajo nivel" de manera rutinaria y sientes constantemente que no quieres hacer esto. Abstraerlos de distancia.

¿Cuándo es demasiado?

Cuando no puede hacer fragmentos de algunas piezas de código de forma regular y tiene que depurarlas hasta la capa anterior. Sientes que esta capa en particular no aporta nada, solo un obstáculo. Déjalo caer.

¿Dónde está el punto óptimo?

Me gusta aplicar el enfoque pragmático. Si ves la necesidad de una abstracción y entiendes cómo mejorará tu vida, adelante. Si ha escuchado que debería haber "oficialmente" una capa extra de abstracción pero no está claro por qué, no lo haga, pero investigue primero. Si alguien insiste en abstraer algo pero no puede explicar claramente lo que traerá, dígales que se vayan.

25

El punto de abstracciones es factor de fuera propiedades comunes de las específicas, como en la operación matemática:

ab + ac => a(b + c) 

Ahora se hace lo mismo con dos operaciones en lugar de tres. Este factoring hizo nuestra expresión más simple.

Un ejemplo típico de abstracción es el sistema de archivos. Por ejemplo, desea que su programa pueda escribir en muchos tipos de dispositivos de almacenamiento: pendrives, tarjetas SD, discos duros, etc. ...

Si no tuviéramos un sistema de archivos, necesitaríamos implementar la lógica de escritura de disco directo, la lógica de escritura de la unidad de pen y la lógica de escritura de tarjeta SD. Pero todas estas lógicas tienen algo en común: crean archivos y directorios, por lo que estas cosas comunes se pueden abstraer, creando una capa de abstracción y proporcionando una interfaz al proveedor de hardware para hacer las cosas específicas.

Cuantas más cosas comparten una propiedad en común.La abstracción más beneficioso puede ser:

ab + ac + ad + ae + af 

a:

a(b + c + d + e + f) 

Esto reduciría las operaciones 9 a 5.

Básicamente, cada buena abstracción reduce a la mitad o menos de la complejidad de un sistema.

Siempre necesita al menos dos cosas que comparten una propiedad común para hacer una abstracción útil. Por supuesto se desgarra una sola cosa aparte por lo que parece una abstracción, pero eso no quiere decir que sea útil:

10 => 5 * 2 

No se puede definir la palabra "común" si tiene una sola entidad.

Para responder a su pregunta. Tiene suficientes abstracciones si hacen que su sistema sea lo más simple posible.

(En mis ejemplos, además conecta las partes del sistema, mientras que la multiplicación define una relación abstracta de hormigón.)

+2

Esto ... solo esto –

+0

Esta respuesta describe el uso de abstracciones para mantener el código SECO, pero no toca otros usos importantes/significativos de la abstracción, por ejemplo Patrones SOLIDOS o GRASP, y contratos de metaprogramación que hacen cumplir la separación de preocupaciones o la consistencia del uso. – jchook