Il est parfois nécessaire de convertir une instance d’un type source <S>
vers un type destination <T>
alors que ces types ne sont pas connus au moment de la compilation.
Divers projets (Apache Common Convert, Spring, etc.)
ont créé leur propres interfaces pour effectuer des conversions d’objets entre des types connus seulement au moment de l’exécution.
Les détails varient, mais ces interfaces ressemblent typiquement à l’interface suivante:
interface ObjectConverter<S,T> { // Certains projets utilisent seulement "Converter" comme nom d’interface.
T apply(S object); // Un autre nom de méthode souvent utilisé par les autres projets est "convert".
}
Comme d’autres projets, Apache SIS définit sa propre interface ObjectConverter
.
La principale différence entre l’interface de SIS est celle que l’on retrouve dans d’autres projets
est que SIS fournit des informations à propos de certaines propriétés mathématiques des convertisseurs.
Un convertisseur de Apache SIS peut avoir aucune, une ou plusieurs des propriétés suivantes:
Exemple:
la conversion Integer
→ String
effectuée par Integer.toString()
est une fonction injective car si deux valeurs de type Integer
ne sont pas égales,
alors il est garanti que leurs conversions produiront différentes valeurs de String
.
En revanche la conversion String
→ Integer
effectuée par Integer.valueOf(String)
n’est pas une fonction injective
parce que plusieurs valeurs distinctes de type String
peuvent être converties vers la même valeur de type Integer
.
Par exemple les conversions des chaînes de caractères "42", "+42" et "0042" donnent toutes la même valeur entière 42.
Exemple:
la conversion String
→ Integer
effectuée par Integer.valueOf(String)
est une fonction surjective car chaque valeur de type Integer
peut être produite
à partir d’un moins une valeur de String
.
En revanche la conversion Integer
→ String
effectuée par Integer.toString()
n’est pas une fonction surjective parce qu’elle ne peut pas produire toutes les valeurs possibles de type String
.
Par exemple il n’y a aucun moyen de produire la valeur "ABC" avec la méthode Integer.toString()
.
Note:
la propriété bijective est définie ici pour des raisons de clarté,
mais en fait n’a pas d’item explicite dans l’énumération FunctionProperty
de Apache SIS.
Ce n’est pas nécessaire puisqu’une fonction qui est à la fois injective et surjective
est nécessairement bijective.
Exemple:
la conversion du type Integer
vers Long
préserve l’ordre naturel des éléments.
Toutefois la conversion du type Integer
vers String
ne préserve pas l’ordre naturel,
parce que des séquences des nombres entiers croissants ont un ordre différents
lorsque les chaînes de caractères sont classées par ordre lexicographique.
Par exemple 1, 2, 10 devient "1", "10", "2".
Exemple: une conversion qui inverse le signe des nombres.
Ces informations peuvent sembler inutiles lorsque l’on convertit des valeurs sans tenir compte du contexte où elles apparaissent. Mais lorsque la valeur à convertir fait parti d’un objet plus gros, alors ces informations peuvent impacter la façon dont la valeur convertie sera utilisée. Par exemple la conversion d’une plage de valeurs représentée par [min … max] est directe lorsque la fonction de conversion préserve l’ordre. Mais si la fonction de conversion renverse l’ordre, alors les valeurs minimale et maximale doivent être interchangées. Par exemple si la fonction de conversion inverse le signe des valeurs, alors la plage convertie sera [-max … -min]. Si la fonction de conversion ne préserve ni ne renverse l’ordre, alors la plage de valeurs ne peut pas être convertie du tout (parce qu’elle ne contiendrait plus le même ensemble de valeurs) même si les valeurs individuelles auraient pu être converties.