2023-06-27
Le modificateur d’accès privé ("#") natif commence à être utilisé dans le code de Pix API et dans plusieurs PR de Pix API.
Ce modificateur d’accès privé ("#") natif :
- remet en cause l'usage historique du underscore ("_")
- entre conflit entre avec les descriptions dans les tests describe("#myMethod"…)
→ De nombreuses personnes souhaitent un partage de connaissances sur le sujet et idéalement une standardisation des pratiques au niveau de Pix.
built-in : fonctionnalité/feature disponible de base dans JavaScript
Programmation orientée objet (POO) = Object-Oriented Programming (OOP)
Member/field/membre/donnée membre/champ : un attribut ou une méthode de classe
Private member/private field = Membre privé/champ privé
Membre privé (private member) → cela s'applique à une classe
(et pas à un module)
La notion de propriété privée (private property) n'existe pas dans ces cas :
- pour les built-in Object ({})
- les modules (ESM, CommonJS)
Les problématiques d'accès existent dans ces cas :
- instances de classe (POO)
- modules (ESM, CommonJS)
MDN : Private class features
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields
(dans la version en-US)
De tout temps, tout ce qui n'est pas exporté n'est pas disponible à l'extérieur du module
Le mot clé built-in export
est nécessaire et suffisant pour cela
Pendant très longtemps la notion de membre privé (private member) n'était pas disponible en JavaScript
La convention de préfixer par _
était donc utilisée pour signifier qu'un membre était privé
Pour les membres privés on a 2 cas chez Pix :
-
côté navigateur
- pour mon-pix, orga, certif, admin, 1d : Ember.js
- pour pix-site, tutos.pix.fr : Nuxt
-
côté serveur (pour api : Node.js)
→ Babel
car les navigateurs à supporter sont assez anciens
Depuis Node.js 12.0.0 (2019) disponibilité du modificateur d’accès privé natif ("#")
Les noms de certains tests du code de Pix suivent les conventions de la communauté Ruby (les années 2010) pour le nommage des méthodes d'instances et de classes :
#do_stuff
.do_more_stuff
https://stackoverflow.com/questions/31413525/test-description-notation-for-attributes
_
est une information visuelle, alors que #
est une info visuelle et une info sémantique au niveau du langage
Les membres préfixés par _
sont toujours appelables par inadvertance ou ignorance
Avoir une propriété privée et un accesseur ayant quasiment le même nom
class OidcAuthenticationService {
#isReady = false;
constructor({
identityProvider,
configKey,
}) {
this.identityProvider = identityProvider;
this.configKey = configKey;
if (!this.configKey) {
logger.error(`${this.constructor.name}: Missing configKey`);
return;
}
this.#isReady = true;
}
get isReady() {
return this.#isReady;
}
}
On ne peut absolument pas accéder à une propriété privée
→ On ne peut pas la stub
→ Cela oblige à tester des comportements plutôt que des implémentations
→ C'est bien cela rend les tests plus métier et plus compréhensibles mais cela peut demander aussi plus de travail
it('returns true', function () {
// given
const oidcAuthenticationService = new OidcAuthenticationService({
identityProvider: 'someIdentityProvider',
configKey: 'someOidcProviderService',
});
// when
const result = oidcAuthenticationService.isReady;
// then
expect(result).to.be.true;
});
A. Dans les classes, utiliser des modificateurs d’accès privé #
natifs pour tout nouveau code
B. Dans les modules, ne pas préfixer par underscore _
les variables et fonctions non-exportées, car la visibilité est déjà exprimée par le fait que l'élément est exporté ou non
B.1. Dans les modules, les variables et fonctions exportées doivent être exportées inline
export const name1 = 'someValue';
export function functionName1() {
// …
}
C. Renommer les noms de tests #aMethod
→.aMethod
, #aProperty
→.aProperty
, car c'est comme ça qu'on y accède
D. Pas d'obligation de modification du code existant
E. Plus tard, mise en place d'une configuration de linting (no-underscore-dangle) pour interdire les _
, avec exceptions locales si pertinent (eslint-disable)
Remarques et questions