En resumen, cada vez que usa "nuevo", está estrechamente acoplando la clase que contiene este código al objeto que se está creando; Para crear una instancia de uno de estos objetos, la clase que hace la instancia debe saber acerca de la clase concreta que se está instanciando. Por lo tanto, cuando use "nuevo", debe considerar si la clase en la que está colocando la instanciación es un "buen" lugar para que resida ese conocimiento, y si está dispuesto a realizar cambios en esta área si la forma del objeto instanciado iban a cambiar.
El acoplamiento apretado, que es un objeto que tiene conocimiento de otra clase concreta, no siempre se debe evitar; en algún nivel, algo, EN ALGÚN LUGAR, tiene que saber cómo crear este objeto, incluso si todo lo demás trata con el objeto al recibir una copia de él desde otro lugar. Sin embargo, cuando la clase que se crea cambia, cualquier clase que conozca la implementación concreta de esa clase debe actualizarse para tratar correctamente los cambios de esa clase.
La pregunta que siempre debe hacer es: "¿Hacer que esta clase sepa cómo crear esta otra clase se convertirá en una responsabilidad al mantener la aplicación?" Ambas metodologías de diseño principales (SOLID y GRASP) generalmente responderían "sí", por razones sutilmente diferentes. Sin embargo, son solo metodologías, y ambas tienen la limitación extrema de que no fueron formuladas en base al conocimiento de su programa único. Como tal, solo pueden errar por el lado de la precaución, y suponen que cualquier punto de acoplamiento apretado EVENTUALMENTE le causará un problema relacionado con la realización de cambios en uno o ambos lados de este punto. Debes tomar una decisión final sabiendo tres cosas; la mejor práctica teórica (que consiste en acoplar libremente todo porque cualquier cosa puede cambiar); el costo de implementar la mejor práctica teórica (que puede incluir varias capas nuevas de abstracción que facilitarán un tipo de cambio mientras obstaculizan otro); y la probabilidad del mundo real de que alguna vez sea necesario el tipo de cambio que está anticipando.
Algunas pautas generales:
Evite el acoplamiento estrecho entre bibliotecas de código compilado. La interfaz entre las DLL (o un EXE y sus DLL) es el lugar principal donde el acoplamiento estrecho presentará una desventaja. Si realiza un cambio en una clase A en DLL X, y la clase B en el EXE principal sabe acerca de la clase A, debe volver a compilar y liberar ambos binarios. Dentro de un solo binario, un acoplamiento más estricto es generalmente más permisible porque el binario completo debe reconstruirse para cualquier cambio de todos modos. A veces, tener que reconstruir múltiples archivos binarios es inevitable, pero debe estructurar su código para que pueda evitarlo cuando sea posible, especialmente en situaciones en las que el ancho de banda es escaso (como implementar aplicaciones móviles; impulsar una nueva DLL en una actualización es mucho más barato) que empujar todo el programa).
Evite el acoplamiento estrecho entre los principales "centros lógicos" de su programa. Puede pensar en un programa bien estructurado que consiste en cortes horizontales y verticales. Los sectores horizontales pueden ser niveles de aplicación tradicionales, como UI, Controlador, Dominio, DAO, Datos; los segmentos verticales pueden definirse para ventanas o vistas individuales, o para "historias de usuario" individuales (como crear un nuevo registro de algún tipo básico). Al hacer una llamada que se mueve hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha en un sistema bien estructurado, generalmente debe abstraer dicha llamada. Por ejemplo, cuando la validación necesita recuperar datos, no debe tener acceso a la base de datos directamente, pero debe hacer una llamada a una interfaz para la recuperación de datos, que está respaldada por el objeto real que sabe cómo hacer esto. Cuando algún control de IU necesita realizar una lógica avanzada que involucre otra ventana, debería abstraer la activación de esta lógica a través de un evento y / o devolución de llamada; no tiene que saber qué se hará como resultado, lo que le permite cambiar lo que se hará sin cambiar el control que lo activa.
En cualquier caso, considere cuán fácil o difícil será hacer un cambio, y qué tan probable será dicho cambio. Si un objeto que está creando solo se usa desde un lugar, y no prevé ese cambio, entonces el acoplamiento apretado generalmente es más permisible, e incluso puede ser superior en esta situación al acoplamiento flojo. El acoplamiento flexible requiere abstracción, que es una capa adicional que evita el cambio a objetos dependientes cuando la implementación de una dependencia debe cambiar. Sin embargo, si la interfaz en sí misma debe cambiar (agregar una nueva llamada al método o agregar un parámetro a una llamada al método existente), entonces una interfaz en realidad aumenta la cantidad de trabajo necesario para realizar el cambio. Debe sopesar la probabilidad de que diferentes tipos de cambio afecten el diseño,