¿Debo escribir una API de interfaz antes de una implementación?

13

Recientemente he estado profundizando en una programación más "organizada" y he aprendido que debería estar programando a una interfaz, no a una implementación. Teniendo esto en cuenta, ¿sería mejor "esbozar" un proyecto en interfaces antes de escribir la implementación para él cuando sea posible?

Y si este es el caso, en el caso de usar bibliotecas de terceros (es decir, Lidgren), ¿debería incluirlas en interfaces y resolverlas a través de contenedores IOC, o está bien exponerlas a las interfaces?

    
pregunta Dan Pantry 06.12.2013 - 10:47

5 respuestas

7

Lamentablemente, encontrará que esto a menudo se reduce a preferencias personales.

Sin embargo, lo que has descrito hasta ahora parece bueno. De hecho, si quisiera (y lo recomiendo) podría utilizar el siguiente enfoque:

  1. Escriba el esqueleto de su aplicación como Interfaces, clases abstractas (apéndices) y clases (aplaudidas)
  2. Escriba sus pruebas contra esas interfaces y apéndices (fallarán por ahora)
  3. Escriba sus implementaciones (sus pruebas comenzarán a aprobarse cuando finalice su implementación)

Te estás enfocando en tratar de escribir código más "organizado". Seguir a TDD te ayudará con esto.

Algunos puntos extra:

  • Los contenedores IoC son convenientes. Úsalos y DI tanto como puedas.
  • Do envuelve bibliotecas de terceros. Esto aflojará el acoplamiento entre su código (código que usted controla) y el código de terceros (código que no controla)
respondido por el MetaFight 06.12.2013 - 10:55
12

Sí, debe codificar contra interfaces en lugar de implementaciones conocidas, y sí, debe crear interfaces primero en lugar de hacerlas emerger de su propio código.

Las razones de ambas recomendaciones son en gran medida las mismas: la programación de computadoras se basa principalmente en factores humanos. Muchos encuentran esto sorprendente, pero considere: hay un número casi infinito de formas diferentes para resolver el mismo problema de computación que funciona igualmente bien. Casi todos son completamente imposibles de entender para cualquiera que no los haya escrito (o, de hecho, al autor poco tiempo después).

De ello se deduce que una buena ingeniería de software es en gran medida acerca de cómo lograr el efecto deseado (cálculo correcto con eficiencia razonable) de una manera que permita trabajar con el código fuente más adelante. Las interfaces y las API son una parte crucial de esa disciplina: le permiten pensar en un problema en un nivel de descripción a la vez. Esto es mucho más fácil que pensar en las reglas de coherencia de negocios y acerca de las implementaciones de listas vinculadas al mismo tiempo, y, por lo tanto, imponer tal separación de preocupaciones es mejor que permitir que el programador cliente para utilizar su código de la manera que más le guste.

Esto es difícil de creer para muchos programadores de cowboy, quienes están convencidos de que entienden todo lo que escriben, son mucho mejores que los pensadores promedio y pueden manejar toda la complejidad que da a los programadores "menos" problemas. No ser consciente de los propios límites cognitivos es un fenómeno extremadamente común: esta es la razón por la cual las mejores prácticas en la organización de códigos son tan importantes (y, por lo tanto, a menudo ignoradas).

Para repetir, las interfaces y las barreras API son en gran medida buenas , incluso cuando solo cooperas contigo mismo. En cuanto a las bibliotecas externas, si traen consigo una API bien pensada, no veo ningún problema en usarla, ya que no se tiene que cambiar esa biblioteca por otra. De lo contrario, un contenedor o una capa anticorrupción puede ser una muy buena idea.

    
respondido por el Kilian Foth 06.12.2013 - 10:58
4

En lugar de solo programar servilmente las interfaces, ¿por qué no analizar el desarrollo / diseño de prueba (TDD)?

Mucha gente piensa que la TDD es una práctica de prueba, pero en realidad es un enfoque de diseño en el que permite que las pruebas muestren cómo se usará su código a través de pruebas (inicialmente a través de pruebas unitarias, pero también a través de pruebas de integración).

La programación en interfaces es un arma importante en su conjunto de herramientas, pero como la mayoría de las cosas, no siempre es la solución / técnica / práctica adecuada, ya que no siempre es necesaria. Debe programar las interfaces donde lo necesite.

El uso de TDD lo obligará a explorar dónde son importantes tales interfaces y dónde, francamente, no importa. Y al final, deberías tener un buen conjunto de pruebas de unidad en tu base de código.

En cuanto al uso de bibliotecas de terceros, le recomiendo que las incluya en sus propias abstracciones cuando sea apropiado; y no dejes que los clientes de tu API "sepan" sobre ellos.

¡Buena suerte!

[edit: vio la respuesta de megaflight - completamente de acuerdo]

    
respondido por el rupjones 06.12.2013 - 11:32
2

Creo que es una exageración. Si el usuario de su API no necesita ser forzado a implementar / usar algo de cierta manera, entonces lo omitiría. Las interfaces son contratos, si no lo necesito, ¿por qué me dan uno?

Creo que la gente sobre uso las interfaces. Está agregando una capa de complejidad que no es necesaria en la mayoría de los casos.

    
respondido por el Kyle Johnson 06.12.2013 - 17:47
1

La programación contra un contrato es casi siempre una buena idea. Ese contrato no necesita ser una interfaz, puede ser cumplido por una clase en su lugar. En mi opinión, las interfaces se han utilizado de forma excesiva junto con DI debido a problemas de pruebas unitarias y marcos burlones.

Personalmente prefiero traer solo interfaces cuando es muy probable que tenga o tenga más de 1 implementación de un contrato. Las interfaces son excelentes para los repositorios donde deseo abstraer el acceso a los datos, pero probablemente menos para mi lógica de negocios estándar, que probablemente sea relativamente inflexible.

Ahora no tener una interfaz puede causar problemas con las pruebas unitarias, especialmente para los puristas. Pero me interesa burlarme de las dependencias externas de mis programas, no de sus dependencias internas. Quiero que mis pruebas realicen la validación del código, no que se haga eco de la estructura del código.

    
respondido por el Peter Smith 07.12.2013 - 00:26

Lea otras preguntas en las etiquetas