Leí las pautas de codificación de TypeScript
Y encontré esta declaración bastante desconcertante:
No use "I" como prefijo para los nombres de interfaz
Es decir, algo como esto no tendría mucho sentido sin el prefijo "I".
class Engine implements IEngine
¿Me estoy perdiendo algo obvio?
Otra cosa que no entendí del todo fue esto:
Clases
Por coherencia, no utilice clases en la canalización del compilador principal. En su lugar, utilice cierres de funciones.
¿Eso indica que no debería usar clases en absoluto?
Espero que alguien pueda aclararlo por mí :)
coding-style
typescript
Snæbjørn
fuente
fuente
I
prefijo tiene sentido para usted y su equipo, ÚSELO. Si no, tal vez el estilo Java deSomeThing
(interfaz) conSomeThingImpl
(implementación) entonces por todos los medios úselo.I
para denotar una interfaz porque es a lo que estoy acostumbrado y tiene sentido para las personas de mi equipo.let engine = new E...
, solo se sugerirán automáticamente las clases. Las interfaces no lo serán. No me había dado cuenta de eso, es una de las razones por las que estaba prefijando 'I'Respuestas:
Cuando un equipo / empresa envía un marco / compilador / conjunto de herramientas, ya tiene algo de experiencia, un conjunto de mejores prácticas. Lo comparten como pautas. Las pautas son recomendaciones . Si no le gusta ninguno, puede ignorarlo. El compilador aún compilará su código. Aunque cuando en Roma ...
Esta es mi visión por la que el equipo de TypeScript recomienda no
I
prefijar interfaces.Razón # 1 Los tiempos de la notación húngara han pasado
El argumento principal de los
I
partidarios de -prefix-for-interface es que el prefijo es útil para asimilar (mirar) inmediatamente si el tipo es una interfaz. La declaración de que el prefijo es útil para asimilar inmediatamente (mirar a escondidas) es una apelación a la notación húngara .I
prefijo para el nombre de la interfaz,C
para la clase,A
para la clase abstracta,s
para la variable de cadena,c
para la variable constante,i
para la variable entera. Estoy de acuerdo en que dicha decoración de nombre puede proporcionarle información de tipo sin pasar el mouse sobre el identificador o navegar hasta la definición de tipo a través de una tecla de acceso rápido. Este pequeño beneficio se ve compensado por las desventajas de la notación húngara y otras razones que se mencionan a continuación. La notación húngara no se utiliza en marcos contemporáneos. C # tieneI
prefijo (y este es el único prefijo en C #) para interfaces debido a razones históricas (COM). En retrospectiva, uno de los arquitectos de .NET (Brad Abrams) piensa que hubiera sido mejor no usar elI
prefijo . TypeScript es COM-legacy-free, por lo que no tiene laI
regla -prefix-for-interface.Razón # 2: el
I
prefijo viola el principio de encapsulaciónSupongamos que obtiene una caja negra. Obtienes algún tipo de referencia que te permite interactuar con ese cuadro. No debería importarle si es una interfaz o una clase. Solo usa su parte de interfaz. Exigir saber qué es (interfaz, implementación específica o clase abstracta) es una violación de la encapsulación.
Ejemplo: supongamos que necesita arreglar API Design Myth: Interface as Contract en su código, por ejemplo, elimine la
ICar
interfaz y useCar
la clase base en su lugar. Entonces debe realizar dicho reemplazo en todos los consumidores.I
-prefix conduce a una dependencia implícita de los consumidores en los detalles de implementación de la caja negra.Razón # 3 Protección de nombres incorrectos
Los desarrolladores son perezosos para pensar correctamente en los nombres. Nombrar es una de las dos cosas difíciles de la informática . Cuando un desarrollador necesita extraer una interfaz, es fácil agregar la letra
I
al nombre de la clase y obtendrá un nombre de interfaz. No permitir elI
prefijo para las interfaces obliga a los desarrolladores a esforzarse en elegir los nombres adecuados para las interfaces. Los nombres elegidos deben ser diferentes no solo en el prefijo, sino también enfatizar la diferencia de intención.Abstracción caso: usted debe no no definir una
ICar
interfaz y un asociadoCar
de clase.Car
es una abstracción y debe ser la utilizada para el contrato. Las implementaciones deben tener nombres descriptivos y distintivos, por ejemploSportsCar, SuvCar, HollowCar
.Buen ejemplo:
WpfeServerAutosuggestManager implements AutosuggestManager
,FileBasedAutosuggestManager implements AutosuggestManager
.Mal ejemplo:
AutosuggestManager implements IAutosuggestManager
.Razón # 4 Los nombres elegidos adecuadamente lo vacunan contra el Mito del Diseño de API: Interfaz como contrato .
En mi práctica, conocí a mucha gente que sin pensarlo duplicaba parte de la interfaz de una clase en una interfaz separada que tenía un
Car implements ICar
esquema de nombres. Duplicar parte de la interfaz de una clase en un tipo de interfaz separada no la convierte mágicamente en abstracción. Aún obtendrá una implementación concreta pero con una parte de interfaz duplicada. Si su abstracción no es tan buena, duplicar la parte de la interfaz no la mejorará de todos modos. Extraer abstracción es un trabajo duro.NOTA: En TS no necesita una interfaz separada para burlarse de las clases o sobrecargar la funcionalidad. En lugar de crear una interfaz separada que describa a los miembros públicos de una clase, puede usar tipos de utilidad de TypeScript . Por ejemplo,
Required<T>
construye un tipo que consta de todos los miembros públicos del tipoT
.export class SecurityPrincipalStub implements Required<SecurityPrincipal> { public isFeatureEnabled(entitlement: Entitlement): boolean { return true; } public isWidgetEnabled(kind: string): boolean { return true; } public areAdminToolsEnabled(): boolean { return true; } }
Si desea construir un tipo que excluya a algunos miembros públicos, puede usar la combinación de Omitir y Excluir .
fuente
I
prefijo es útil para asimilar inmediatamente si el tipo tiene una implementación o no. La principal ventaja de utilizar interfaces es no acoplar los detalles de implementación del código externo a una implementación específica.I
yImpl
es difícil ("Solo hay dos cosas difíciles en Ciencias de la Computación: invalidación de caché y nombrar cosas" - Phil Karlton) pero es factible.Aclaración sobre el enlace al que hace referencia:
Si usar el
I
prefijo tiene sentido para usted y su equipo, utilícelo (yo lo hago).Si no, tal vez el estilo Java de
SomeThing
(interfaz) conSomeThingImpl
(implementación) entonces por todos los medios úselo.fuente
In general, do not prefix interfaces with I (e.g. IColor). Because the concept of an interface in TypeScript is much more broad than in C# or Java, the IFoo naming convention is not broadly useful.
No es estricto, pero parece una recomendación sólida.I
. En un proyecto de React tenemosCard
que es una interfaz y un componente llamadoCard
. En los accesorios, necesito una matriz deCard
, pero el tipo no el componente. Tengo que elegir nombrarICard
oCardComponent
...SomeThingImpl implements SomeThing
es tan bueno comoSomeThing implements ISomeThing
. SiSomeThing
es una abstracción, entonces la denominación debería serloConcrete[Some]Thing implements SomeThing
.Encuentro que @ stanislav-berkov es una respuesta bastante buena a la pregunta del OP. Solo compartiría mis 2 centavos agregando que, al final, depende de su Equipo / Departamento / Compañía / Lo que sea llegar a un entendimiento común y establecer sus propias reglas / pautas a seguir.
Cumplir con los estándares y / o convenciones, siempre que sea posible y deseable, es una buena práctica y facilita la comprensión de las cosas. Por otro lado, me gusta pensar que todavía somos libres de elegir la forma en que escribimos nuestro código.
Pensando un poco en el lado emocional, la forma en que escribimos el código o nuestro estilo de codificación refleja nuestra personalidad y, en algunos casos, incluso nuestro estado de ánimo. Esto es lo que nos mantiene a los humanos y no solo a las máquinas de codificación siguiendo reglas. Creo que la codificación puede ser un oficio, no solo un proceso industrializado.
fuente
El tipo de interfaz es un detalle de implementación. Los detalles de implementación deben estar ocultos en API: s. Es por eso que debes evitarlo
I
.Debe evitar tanto
prefix
ysuffix
. Ambos están mal:ICar
CarInterface
Lo que debe hacer es hacer visible un nombre bonito en la API y tener los detalles de implementación ocultos en la implementación. Por eso propongo:
Car
- Una interfaz que se expone en la API.CarImpl
- Una implementación de esa API, que está oculta al consumidor.fuente
Impl
sufijo tendrá el efecto secundario de reemplazar cualquier sabelotodo que lo esté regañando por elI
prefijo con el tío Bob.