Nous avons une fonction API qui décompose un montant total en montants mensuels en fonction de dates de début et de fin données.
// JavaScript
function convertToMonths(timePeriod) {
// ... returns the given time period converted to months
}
function getPaymentBreakdown(total, startDate, endDate) {
const numMonths = convertToMonths(endDate - startDate);
return {
numMonths,
monthlyPayment: total / numMonths,
};
}
Récemment, un consommateur de cette API a voulu spécifier la plage de dates de différentes manières: 1) en indiquant le nombre de mois au lieu de la date de fin, ou 2) en fournissant le paiement mensuel et en calculant la date de fin. En réponse à cela, l'équipe de l'API a modifié la fonction comme suit:
// JavaScript
function addMonths(date, numMonths) {
// ... returns a new date numMonths after date
}
function getPaymentBreakdown(
total,
startDate,
endDate /* optional */,
numMonths /* optional */,
monthlyPayment /* optional */,
) {
let innerNumMonths;
if (monthlyPayment) {
innerNumMonths = total / monthlyPayment;
} else if (numMonths) {
innerNumMonths = numMonths;
} else {
innerNumMonths = convertToMonths(endDate - startDate);
}
return {
numMonths: innerNumMonths,
monthlyPayment: total / innerNumMonths,
endDate: addMonths(startDate, innerNumMonths),
};
}
Je pense que ce changement complique l'API. Maintenant , l'appelant a besoin de se soucier de la heuristiques cachés avec la mise en œuvre de la fonction pour déterminer quels paramètres prennent la préférence à être utilisé pour calculer la plage de dates (par exemple par ordre de priorité monthlyPayment
, numMonths
, endDate
). Si un appelant ne prête pas attention à la signature de la fonction, il peut envoyer plusieurs des paramètres facultatifs et se demander pourquoi il endDate
est ignoré. Nous spécifions ce comportement dans la documentation de la fonction.
De plus, j'estime que cela crée un mauvais précédent et ajoute des responsabilités à l'API avec lesquelles elle ne devrait pas se préoccuper (c.-à-d. Violer SRP). Supposons que des consommateurs supplémentaires souhaitent que la fonction prenne en charge davantage de cas d'utilisation, tels que le calcul à total
partir des paramètres numMonths
et monthlyPayment
. Cette fonction deviendra de plus en plus compliquée avec le temps.
Ma préférence est de garder la fonction telle quelle et d'exiger que l'appelant calcule lui- endDate
même. Cependant, je peux me tromper et je me demandais si les modifications apportées étaient un moyen acceptable de concevoir une fonction API.
Sinon, existe-t-il un modèle commun pour gérer des scénarios comme celui-ci? Nous pourrions fournir dans notre API des fonctions supplémentaires d'ordre supérieur qui encapsulent la fonction d'origine, mais cela alourdit l'API. Nous pourrions peut-être ajouter un paramètre indicateur supplémentaire spécifiant quelle approche utiliser dans la fonction.
Date
- vous pouvez fournir une chaîne et il peut être analysé pour déterminer la date. Cependant, de cette façon, les paramètres de manipulation peuvent également être très pointilleux et peuvent produire des résultats peu fiables. Voir à Date
nouveau Il n’est pas impossible de bien faire les choses - Moment le gère beaucoup mieux, mais c’est très agaçant de l’utiliser quand même.
monthlyPayment
est donné mais total
n'est pas un multiple entier de celui-ci. Et aussi comment traiter d'éventuelles erreurs d'arrondi en virgule flottante s'il n'est pas garanti que les valeurs soient des entiers (par exemple, essayez avec total = 0.3
et monthlyPayment = 0.1
).