Prefijando interfaces con I?


Actualmente estoy leyendo "Código limpio" De Rober Martin (UncleBob), y en general me encantan las reflexiones de UncleBob. Sin embargo, me confundí un poco, cuando leí que evita prefijar interfaces como "IPerson". Afirma "No quiero que mis usuarios sepan que les estoy entregando una interfaz".

Pensando en la perspectiva TDD/inyección, siempre estaré muy interesado en decirle a los "usuarios" de mis clases que estoy entregando una interfaz. La razón principal es que considero las interfaces contratos entre los diferentes "agentes" de un sistema. Un agente que trabaja con una esquina de mi sistema, no debe saber la implementación concreta de otro trabajo de agentes; solo deben intercambiar contratos, y esperar que los contratos se cumplan sin saber cómo. La otra razón, pero también muy importante, es que una interfaz se puede burlar por completo, y por lo tanto hacer pruebas unitarias mucho más fácil. Hay límites a cuánto puedes burlarte en una clase concreta.

Por lo tanto, prefiero visualiza que estoy entregando una interfaz... o tomando una interfaz como argumento. Pero dado que UncleBob es un campeón de peso pesado en nuestra comunidad, y yo solo soy otro jinete de escritorio de peso volador, me gustaría saber si me estoy perdiendo algo.

¿Está mal que insista en I en interfaces??

Author: BЈовић, 2011-04-28

3 answers

Hay una serie de convenciones en Java y C# con las que nos hemos sentido cómodos; pero que están al revés. Por ejemplo, la convención de poner variables privadas en la parte superior de cada clase es bastante tonta desde un punto de vista técnico. Lo más importante de una clase son sus métodos públicos. Las menos cosas importantes, las cosas que escondemos detrás de una barrera de privacidad, son las variables de instancia. Entonces, ¿por qué los pondríamos en la parte superior?

La " I " delante de interfaces es otra convención hacia atrás. Cuando se le pasa una referencia a un objeto, debe esperar que sea una interfaz. Las interfaces deben ser las predeterminadas; así que no tiene sentido hacer algo extra, como usar un prefijo I, para anunciar que estás haciendo lo que todos esperan que hagas. Sería mejor (aunque todavía incorrecto) si reserváramos un marcador especial para la condición excepcional de pasar una clase concreta.

Otro problema con el uso de I, es que (extrañamente) lo usamos para comunicar la decisión de implementación de usar una interfaz. Por lo general, no queremos que las decisiones de implementación se expresen tan fuerte, porque eso las hace difíciles de cambiar. Considere, por ejemplo, lo que podría suceder si decidiera que IFoo realmente debería ser una clase abstracta en lugar de una interfaz. ¿Debe cambiar el nombre a Foo o CFoo, o ACFoo?

Puedo oír las ruedas girando en tu cabeza. Usted está pensando: "Sí, pero las interfaces tienen un lugar especial en el idioma, por lo que es razonable marcarlos con una convención de nomenclatura especial."Eso es verdad. Pero los enteros también tienen un lugar especial en el lenguaje, y no los marcamos (más). Además, pregúntese esto, ¿por qué las interfaces tienen un lugar especial en el lenguaje?

Toda la idea detrás de las interfaces en Java y C# fue una excusa. Los diseñadores de lenguaje podrían haber utilizado clases abstractas, pero estaban preocupados por las dificultades de implementación de herencia múltiple. Así que hicieron un trato con ellos mismos. Inventaron una construcción artificial (es decir, interfaces) que proporcionaría algunos del poder de la herencia múltiple, y restringieron las clases normales a la herencia única.

Esta fue una de las peores decisiones que tomaron los diseñadores de lenguaje. Inventaron un nuevo y pesado elemento de sintaxis para excluir una característica útil y poderosa (aunque controvertida) del lenguaje. Las interfaces no se inventaron para habilitar, se inventaron para deshabilitar. Las interfaces son un truco colocado en el lenguaje por diseñadores que no querían resolver el problema más difícil de MI. Así que cuando usas el prefijo I, estás poniendo un gran foco en uno de los hacks más grandes en la historia del lenguaje.

La próxima vez que escriba una firma de función como esta:

public void myFunction(IFoo foo) {...}

Pregúntate esto: "¿Por qué quiero saber que el autor de IFoo usó la palabra 'interfaz'? Qué diferencia ¿me hace saber si usó 'interfaz' o ' clase 'o incluso'estructura'? ¡Eso es asunto suyo, no mío! Entonces, ¿por qué me está forzando a conocer su negocio al poner este gran yo delante de su nombre tipo? ¿Por qué no cierra sus declaraciones y mantiene sus partes privadas fuera de mi vista?"

 55
Author: Robert Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-25 10:47:14

Si estás hablando de.NET, entonces las interfaces con I al principio son tan ubicuas que dejarlas caer confundiría a todos.

Además, preferiría tener

public class Foo : IFoo {}

Que

public class FooImpl : Foo {}

Todo se reduce a la preferencia personal y por un tiempo jugué con la idea yo mismo, pero volví al prefijo I. YMMV

 8
Author: Krzysztof Kozmic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-28 10:13:50

Considero contratos de interfaces entre los diferentes "agentes" de un sistema. Un agente trabajando con uno esquina de mi sistema, no debería saber la aplicación concreta de otro los agentes trabajan; solo deben intercambiar contratos, y esperar que los contratos ser realizado sin saber cómo. El otro, pero también muy importante, razón es que una interfaz puede ser burlado totalmente, y por lo tanto haciendo pruebas unitarias mucho más fácil. Hay límites a cómo mucho de lo que puedes burlarte en una clase concreta.

Todo esto es cierto, pero ¿cómo se necesita una convención de nomenclatura para las interfaces?

Básicamente, prefijar interfaces con "I" no es más que otro ejemplo del tipo inútil de notación húngara, porque en un lenguaje estáticamente tipado (el único tipo donde las interfaces como construcción de lenguaje tienen sentido) siempre puede averiguar fácil y rápidamente qué es un tipo, generalmente pasando el mouse sobre él en el IDE.

 6
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-28 10:17:20