No estructurar los datos completamente hacia abajo

7

En la publicación del blog No estructurar los datos completamente hacia abajo , el autor analiza diferentes formas de estructurar un círculo. tipo de datos y cómo implementar los parámetros a una función de Radius.

area({circle, {point,0,0}, 17.4})

Un poco desordenado. ¿Qué tal una función para construir un círculo para nosotros? Entonces podríamos hacer esto:

area(make_circle(0, 0, 17.4))

También podríamos tener una versión más corta de make_circle que solo toma un radio, por defecto el punto central a 0,0. Está bien, para, nos estamos diseñando hasta la muerte. Todo lo que necesitamos es una función simple para calcular el área de un círculo:

area(R) -> math:pi() * R * R.

Está hablando de las funciones en el lenguaje Erlang, que es funcional y no está orientada a objetos (OO). Mi pregunta es, ¿este argumento es válido para los idiomas OO y para los lenguajes funcionales?

    
pregunta spirc 22.04.2012 - 08:54

6 respuestas

5

Supongo que la esencia de esto es "no sobre-diseñar". El equivalente de OOP de su argumento usaría una clase Circle , un poco como esta (se asume un lenguaje de OOP basado en clases canónico pero hipotético):

public class Circle {
    private Point center;
    private double radius;
    public Circle(Point, radius) { ... }
    public Circle(radius) { ... }
    public double getArea() { return radius * radius * Math.PI; }
}

... cuando, de hecho, todo lo que necesitas es:

public double getCircleArea(double radius) { return radius * radius * Math.PI; }

Por supuesto, "la ingeniería excesiva es mala" es una declaración fácil de hacer, y la ingeniería insuficiente es igualmente mala. El truco es encontrar exactamente el nivel correcto de abstracción y aprender esto requiere experiencia.

Sin embargo, la programación orientada a objetos es especialmente vulnerable a la trampa de ingeniería excesiva, ya que ofrece muchas formas ingeniosas de agregar capas de abstracción; la mayoría de las veces, agregar otra abstracción en la parte superior de tu pila parece ser lo correcto, aunque con demasiada frecuencia no lo es.

    
respondido por el tdammers 22.04.2012 - 15:55
4

El punto es "No lo vas a necesitar" (también conocido como YAGNI) y, por lo tanto, no debes implementarlo. Esto no tiene nada que ver con el paradigma de programación (OO o funcional).

    
respondido por el scarfridge 22.04.2012 - 09:34
2

Creo que la respuesta depende completamente del contexto. Casi siempre tiene sentido crear abstracciones para cualquier cosa que potencialmente se repita en cualquier lugar de una aplicación, incluso si esa abstracción es solo ligera, es más probable que proporcione un código más limpio más arriba

Por ejemplo, su capa lógica podría necesitar construir un algoritmo más complicado que determine si dos círculos se tocan o se intersecan, y determinar los puntos en los que se tocan; este tipo de código beneficiaría a la OMI con la capacidad de condensar dos conjuntos de X, Y, Radio en una sola estructura. - El usuario del algoritmo probablemente está tratando específicamente con círculos en este caso, y el propio círculo puede terminar con una interfaz más grande que simplemente Get / Set.

En el otro extremo, a veces una estructura es simplemente una exageración si la abstracción termina siendo un uso único "desechable"; si el círculo no tiene otro uso potencial, excepto por un solo escenario localizado que calcula el área, entonces es muy El simple área de cálculo funcionaría bien

    
respondido por el Ben Cottrell 22.04.2012 - 09:34
1

Al utilizar un lenguaje OO o un estilo OO, tiene una jerarquía de elementos de estructura. Por ejemplo (intencionalmente muy simplificado):

  1. declaraciones, variables
  2. funciones / funciones de miembro
  3. clases / objetos
  4. bibliotecas / componentes -

Por lo general, se construyen clases más o menos complicadas a partir de bloques de construcción más simples como funciones y variables. Y me parece que de eso se trata la publicación del blog: mantener los bloques de construcción de nivel inferior (como una función para calcular el área del círculo) simple, y la estructura de datos "una capa arriba", que podría ser una "clase" en un lenguaje OO. Esto puede ser bastante obvio para alguien que está acostumbrado a diseñar estructuras de datos de una manera OO, pero puede no ser tan obvio cuando se usa un estilo funcional puro.

De hecho, eso no significa que debas implementar alguna vez algo como una función de área fuera del alcance de una clase circular; simplemente no debes darle parámetros que no necesitarán de todos modos (como las coordenadas X / Y).

    
respondido por el Doc Brown 22.04.2012 - 09:35
0

Creo que esto se puede resumir en que no se crea un objeto solo para invocar un solo método y luego destruirlo, y este es un buen consejo en el mundo de la POO. Recuerdo haber visto un video de Pycon en infact .

En el mundo funcional, especialmente en Haskell (como es perezoso), lo contrario es a menudo cierto. Un patrón común es construir una enorme estructura de datos, solo para descomponerla inmediatamente. Al ser perezoso y si se hace bien, Haskell no usa mucha memoria haciendo esto.

    
respondido por el dan_waterworth 22.04.2012 - 09:37
0

El punto que veo en ese ejemplo del área del círculo es que sus funciones no deben requerir parámetros que no usen.

Una función de área circular solo necesita conocer el radio, por lo que solo debe tomar el radio como parámetro. Este principio puede extenderse desde funciones simples a cualquier porción de código de tamaño. Sus clases no deben depender de otro código que no necesiten. Del mismo modo, sus archivos DLL solo deberían requerir otros archivos DLL que realmente necesitan .

Minimizar las dependencias y los datos que requiere su código hace que sea inherentemente más fácil de usar y más fácil de reutilizar. También hace que las pruebas unitarias sean mucho más fáciles.

    
respondido por el Philip 22.04.2012 - 16:11

Lea otras preguntas en las etiquetas