Nota: Traducido de la versión original en Inglés.
Code Complete es uno de esos libros que todo desarrollador debería leer. Hay una sección en el capítulo 5 de este libro que habla sobre acoplamiento. Aunque el acoplamiento entre entidades de software no es totalmente evitable en todas sus formas incluso en programas sencillos, hay un tipo especial de acoplamiento que todos los desarrolladores deberíamos condenar: El Acoplamiento semántico. Según Code Complete:
“El tipo más insidioso de acoplamiento ocurre cuando un módulo hace uso, no de algún elemento sintáctico de otro módulo, sino de algún conocimiento semántico de los detalles internos del funcionamiento de otro módulo”.
He escrito código con acoplamiento semántico, lo confieso. Aunque no creo que sea una confesión muy escandalosa. He descubierto que prácticamente todos los desarrolladores con los que he trabajado tienen acoplamiento semántico en sus antecedentes criminales. Con el objetivo de hacer del mundo de la programación un lugar un poco más legal, permíteme mostrarte dos ejemplos básicos de acoplamiento semántico que encontré en mi propio código:
Descargo de responsabilidad: Los nombres de clases y métodos han sido cambiados para proteger a los clientes del autor y a los clientes de los clientes del autor.
Ejemplo 1. Evitar llamar a un método porque otro método lo hace.
class SomeUIComponent {
public void init() {
setSizefull();
...
}
public setSizefull() {
...
}
}
class AnotherClass {
public void smartassMethod() {
SomeUIComponent c = new SomeUIComponent();
c.init();
// Sé que necesito llamar a c.setSizeFull pero también sé
// que SomeUIComponent.init() lo llamará, así que todo está bien :D
}
}
No, eso no está bien. Y deja de sonreír. Yo también he hecho esto pensando, “sé que no está muy bien, pero la mayoría de las instancias de SomeUIComponent
serán “full-size”, así que pongamos eso en el método init”. Aunque la razón suene bien, sigue siendo acoplamiento semántico, querido amigo.
Ejemplo 2. Downcasting.
class User {
...
}
class MightyUser extends User {
public mightyMethod() {
...
}
}
class AnotherClass {
public void method() {
MightyUser u = new MightyUser();
doThatThing(u);
}
public void doThatThing(User u) {
// Sé que pasarán a uno Mighty, así que hagamos un cast :D
MightyUser u2 = (MightyUser) u;
u2.mightyMethod();
...
}
}
¿Hagamos un cast? Cínico desarrollador. Eso es downcasting. Y deja de sonreír otra vez. A veces me sorprendo pensando, “debería cambiar la firma del método”, pero encuentro una razón para no hacerlo. Quizás sea imposible cambiar la firma debido a restricciones externas (el método está declarado en una interfaz o superclase, por ejemplo). Puede parecer una buena razón, pero de nuevo, sigue siendo acoplamiento semántico.
Si encuentras algo como lo anterior mientras programas, míralo como una oportunidad para pensar en un mejor diseño. Hay muchas oportunidades para mejorar cuando te enfrentas a ese fenómeno llamado acoplamiento semántico, un sabor repugnante de acoplamiento que realmente no querrás probar. Entonces, podrás sonreír si quieres.