He estado profundizando en una programación más "organizada" recientemente y he estado aprendiendo que debería programar en una interfaz, no en una implementación. Con eso en mente, ¿sería mejor "esbozar" un proyecto en las interfaces antes de escribir la implementación para ello cuando sea posible?
Y si este es el caso, en el caso de usar bibliotecas de terceros (es decir, Lidgren), ¿debería envolverlas también en las interfaces y resolverlas a través de contenedores IOC, o está bien exponerlas a las interfaces?
Respuestas:
Desafortunadamente, encontrará que esto a menudo se reduce a preferencias personales.
Sin embargo, lo que has descrito hasta ahora parece bueno. De hecho, si quisieras (y lo recomiendo) podrías usar el siguiente enfoque:
Te estás enfocando en tratar de escribir más código "organizado". Seguir TDD lo ayudará con esto.
Algunos puntos extra:
fuente
Sí, debe codificar contra interfaces en lugar de implementaciones conocidas, y sí, debe construir interfaces primero en lugar de hacer que emerjan de su propio código.
Las razones de ambas recomendaciones son en gran medida las mismas: la programación de computadoras se trata principalmente de factores humanos. Muchos encuentran esto sorprendente, pero consideren: hay un número casi infinito de formas diferentes de resolver el mismo problema informático que funcionan igualmente bien. Casi todos son completamente imposibles de entender para cualquiera que no los haya escrito (o de hecho para el autor poco tiempo después).
De ello se deduce que una buena ingeniería de software se trata en gran medida 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 reglas de coherencia empresarial y en implementaciones de listas vinculadas al mismo tiempo, y por lo tanto, imponer tal separación de preocupaciones a la fuerza es mejor que permitir que el programador del cliente use su código de la manera que desee.
Esto es difícil de creer para muchos programadores de vaqueros, que están convencidos de que entienden todo lo que escriben, son mucho mejores que los pensadores promedio y pueden manejar toda la complejidad que les da problemas a los programadores "menores". 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 tan 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, siempre y cuando no anticipe tener que cambiar esa biblioteca por otra. De lo contrario, una capa de envoltura o anticorrupción puede ser una muy buena idea.
fuente
IBlah
implementado porBlah
, oBlah
implementado porBlahImpl
. No me gustan ambos, y tiendo a usarBlah
implementado porOralBlah
,WrittenBlah
oASLBlah
. Pero, como de costumbre, es más importante ajustarse a su base de código y expectativas existentes que a cualquier estándar general.En lugar de simplemente servir como programador a interfaces, ¿por qué no buscar en el Desarrollo / Diseño de Prueba (TDD)?
Mucha gente piensa en TDD como una práctica de prueba, pero en realidad es un enfoque de diseño en el que permite que las pruebas expongan cómo se usará su código a través de pruebas (inicialmente a través de pruebas unitarias, pero también puede ser a través de pruebas de integración).
La programación para 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 en las interfaces donde lo necesite.
El uso de TDD lo obligará a explorar dónde tales interfaces son importantes y dónde, francamente, no importa. Y al final, debe tener un conjunto bastante bueno de pruebas unitarias en su base de código.
En cuanto al uso de bibliotecas de terceros, recomiendo encarecidamente incluirlas en sus propias abstracciones cuando corresponda; y no dejar que los clientes de su API "sepan" sobre ellos.
¡Buena suerte!
[editar: vi la respuesta de megaflight - completamente de acuerdo]
fuente
Creo que es exagerado. Si el usuario de su API no necesita ser forzado a implementar / usar algo de cierta manera, entonces lo dejaría fuera. Las interfaces son contratos, si no lo necesito, ¿por qué darme uno?
Creo que las personas usan en exceso las interfaces. Está agregando una capa de complejidad que no es necesaria en la mayoría de los casos.
fuente
La programación contra un contrato es casi siempre una buena idea. Ese contrato no necesita ser una interfaz, sino que una clase puede cumplirlo. En mi opinión, las interfaces se han usado en exceso junto con DI debido a preocupaciones de prueba de unidad y marcos de trabajo 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 repositorios donde deseo abstraer el acceso a datos, pero probablemente no tanto para mi lógica comercial estándar que probablemente sea relativamente inflexible.
Ahora no tener una interfaz puede causar problemas con las pruebas unitarias, especialmente para los puristas. Pero estoy interesado en 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 hagan eco de la estructura del código.
fuente