18  Conception de packages

Le chapitre A36/F29  contient des directives pour la conception de packages. Notez que la notion de package n’existe pas en TypeScript (et en JavaScript), mais le principe de namespace (espace de nom) existe. La Section 18.1 explique quelques pratiques pour la gestion des namespaces en TypeScript.

Les points importants sont les suivants (les détails se trouvent dans le livre) :

La figure 18.1 est un exemple d’un diagramme de packages.

Services TechniquesDomainePersistanceSécuritéJournalisationPOSStocksTaxes

Figure 18.1: Diagramme de packages (tiré de la figure F12.6 ). (PlantUML)

18.1 Absence de packages dans TypeScript

En effet, TypeScript n’a pas la notion de package comme dans C# ou Java. Cependant, il y a des pratiques pour organiser logiquement le code et pour éviter les conflits (les collisions) de noms. Rappelons que la notion de package existe dans Java pour :

  1. Organiser logiquement le code : le type interface java.util.List est disponible dans la bibliothèque java.util) ;
  2. Éviter les conflits de noms : les classes java.util.List et ca.etsmtl.log121.fuhrman.projet2.List ont le même nom de base, mais puisqu’elles sont dans deux packages différents, elles peuvent être utilisées dans le même programme (leur « fully qualified name » est différent).

En TypeScript, on peut atteindre les mêmes objectifs.

18.1.1 Organisation des éléments du code

L’organisation peut être réalisée grâce aux modules avec les mots-clés export et import. Par exemple :

// maClasse.ts
export class MaClasse {
  // définition
}
// client.ts
import { MaClasse } from './maClasse'

On organise les fichiers, par exemple maClasse.ts, dans les répertoires.

18.1.2 Noms sans conflit

Dans l’exemple précédent, il ne serait pas possible d’avoir deux fichiers nommés maClasse.ts dans le même répertoire, alors il est impossible d’avoir une collision avec le nom du fichier. Donc, on pourrait importer la classe MaClasse de maClasse.ts et la classe MaClasse de lib/projet2/maClasse.ts dans le même programme. Cependant, pour éviter un conflit de noms, on emploie le mot-clé as pour renommer la classe (MaClasseP2) lorsqu’on l’importe :

// client.ts
import { MaClasse } from './maClasse'
import { MaClasse as MaClasseP2 } from './lib/projet2/maClasse'

18.1.3 Namespaces

TypeScript offre une autre manière pour organiser et éviter les conflits de noms avec les namespaces (anciennement les modules internes). L’exemple de Validators est intéressant puisqu’il s’agit d’un namespace commun réparti dans plusieurs fichiers. C’est à utiliser surtout lorsqu’on ne veut pas centraliser tout le code dans un seul (gros) fichier (avec export). Mais, comme vous le voyez dans l’exemple, on doit utiliser les commentaires dans le code de certains fichiers, par exemple
/// <reference path="Validation.ts" />, et c’est plus compliqué à maintenir.