Maison  >  Article  >  interface Web  >  Une introduction détaillée aux principes de conception des API JavaScript

Une introduction détaillée aux principes de conception des API JavaScript

黄舟
黄舟original
2017-03-08 15:02:071298parcourir

Il y a quelque temps, nous avons organisé et optimisé notre API de module natif (les modules iOS et Android sont encapsulés dans des interfaces JavaScript), j'ai donc étudié plusieurs articles sur la conception d'API JavaScript. Bien qu'il s'agisse d'articles anciens, j'ai étudié plusieurs articles sur la conception d'API JavaScript. J’en ai beaucoup bénéficié. Enregistrez-le ici.

Bonne conception d'API : atteindre l'objectif d'abstraction tout en étant auto-descriptif.

Avec une API bien conçue, les développeurs peuvent démarrer rapidement. Il n'est pas nécessaire de conserver fréquemment des manuels et des documents, et il n'est pas nécessaire de consulter fréquemment la communauté d'assistance technique.

Interface fluide

Chaîne de méthodes : fluide et facile à lire, plus facile à comprendre

//常见的 API 调用方式:改变一些颜色,添加事件监听
var elem = document.getElementById("foobar");
elem.style.background = "red";
elem.style.color = "green";
elem.addEventListener('click', function(event) {
  alert("hello world!");
}, true);

//(设想的)方法链 API
DOMHelper.getElementById('foobar')
  .setStyle("background", "red")
  .setStyle("color", "green")
  .addEvent("click", function(event) {
    alert("hello world");
  });

Les opérations de définition et d'obtention peuvent être combiné D'une part, plus il y a de méthodes, plus la documentation peut être difficile à écrire

var $elem = jQuery("#foobar");

//setter
$elem.setCss("background", "green");
//getter
$elem.getCss("color") === "red";

//getter, setter 合二为一
$elem.css("background", "green");
$elem.css("color") === "red";

Cohérence

Les interfaces pertinentes maintiennent un style cohérent et un ensemble complet d'API transmet un sentiment de familiarité et de confort. Ce sentiment facilitera grandement l’adaptabilité des développeurs aux nouveaux outils.

Nommez cette chose : elle doit être courte, auto-descriptive et surtout cohérente

« Il n'y a que deux problèmes difficiles en informatique : l'invalidation du cache et la dénomination des choses. »
« Il n'y a que deux maux de tête en informatique : les invalidations de cache et les problèmes de nommage »
—Phil Karlton

Choisissez un mot que vous aimez et continuez à l'utiliser. Choisissez un style et gardez-le ainsi.

Paramètres de traitement

Vous devez considérer la façon dont les gens utilisent la méthode que vous fournissez. Sera-t-elle appelée à plusieurs reprises ? Pourquoi est-il appelé à plusieurs reprises ? Comment votre API aide-t-elle les développeurs à réduire les appels en double ?
Recevez des paramètres de mappage de carte, des rappels ou des noms d'attributs sérialisés, ce qui non seulement rend votre API plus propre, mais la rend également plus confortable et efficace à utiliser.

La méthode css() de jQuery peut définir des styles pour les éléments DOM :

jQuery("#some-selector")
  .css("background", "red")
  .css("color", "white")
  .css("font-weight", "bold")
  .css("padding", 10);

Cette méthode peut accepter un objet JSON :

jQuery("#some-selector").css({
  "background" : "red",
  "color" : "white",
  "font-weight" : "bold",
  "padding" : 10
});

//通过传一个 map 映射绑定事件
jQuery("#some-selector").on({
  "click" : myClickHandler,
  "keyup" : myKeyupHandler,
  "change" : myChangeHandler
});

//为多个事件绑定同一个处理函数
jQuery("#some-selector").on("click keyup change", myEventHandler);

Type de traitement

Lors de la définition d'une méthode, vous devez décider quels paramètres elle peut recevoir. Nous ne savons pas comment les gens utilisent notre code, mais nous pouvons être plus prospectifs et réfléchir aux types de paramètres que nous prenons en charge.

//原来的代码
DateInterval.prototype.days = function(start, end) {
  return Math.floor((end - start) / 86400000);
};

//修改后的代码
DateInterval.prototype.days = function(start, end) {
  if (!(start instanceof Date)) {
    start = new Date(start);
  }
  if (!(end instanceof Date)) {
    end = new Date(end);
  }

  return Math.floor((end.getTime() - start.getTime()) / 86400000);
};

Avec seulement 6 lignes de code ajoutées, notre méthode est suffisamment puissante pour accepter des Date objets, des horodatages numériques et même des chaînes comme Sat Sep 08 2012 15:34:35 GMT 0200 (CEST)

Si vous devez vous assurer le type du paramètre entrant (string, number, Boolean), vous pouvez le convertir comme ceci :

function castaway(some_string, some_integer, some_boolean) {
  some_string += "";
  some_integer += 0; // parseInt(some_integer, 10) 更安全些
  some_boolean = !!some_boolean;
}

Handle undefined

Afin de rendre votre API plus robuste, vous devez identifiez si la valeur réelle undefined est transmise, vous pouvez vérifier l'objet arguments :

function testUndefined(expecting, someArgument) {
  if (someArgument === undefined) {
    console.log("someArgument 是 undefined");
  }
  if (arguments.length > 1) {
    console.log("然而它实际是传进来的");
  }
}

testUndefined("foo");
// 结果: someArgument 是 undefined
testUndefined("foo", undefined);
// 结果:  someArgument 是 undefined , 然而它实际是传进来的

Nommez le paramètre

event.initMouseEvent(
  "click", true, true, window,
  123, 101, 202, 101, 202,
  true, false, false, false,
  1, null);

Event.initMouseEvent Cette méthode est tout simplement folle , si vous ne lisez pas la documentation, quelqu'un peut-il dire ce que signifie chaque paramètre ?

Donnez un nom à chaque paramètre et attribuez une valeur par défaut. Par exemple,

event.initMouseEvent(
  type="click",
  canBubble=true,
  cancelable=true,
  view=window,
  detail=123,
  screenX=101,
  screenY=202,
  clientX=101,
  clientY=202,
  ctrlKey=true,
  altKey=false,
  shiftKey=false,
  metaKey=false,
  button=1,
  relatedTarget=null);

ES6, ou Harmony a des valeurs de paramètres par défaut et des paramètres de repos.

Le paramètre reçoit un objet JSON

Au lieu de recevoir un tas de paramètres, il vaut mieux recevoir un objet JSON :

function nightmare(accepts, async, beforeSend, cache, complete, /* 等28个参数 */) {
  if (accepts === "text") {
    // 准备接收纯文本
  }
}

function dream(options) {
  options = options || {};
  if (options.accepts === "text") {
    // 准备接收纯文本
  }
}

C'est aussi plus simple à appeler :

nightmare("text", true, undefined, false, undefined, /* 等28个参数 */);

dream({
  accepts: "text",
  async: true,
  cache: false
});

Valeurs par défaut des paramètres

Il est préférable d'avoir des valeurs par défaut pour les paramètres. Les valeurs par défaut prédéfinies peuvent être remplacées via jQuery.extend() http://. www.php.cn/) et Object.extend de Protoype.

var default_options = {
  accepts: "text",
  async: true,
  beforeSend: null,
  cache: false,
  complete: null,
  // …
};

function dream(options) {
  var o = jQuery.extend({}, default_options, options || {});
  console.log(o.accepts);
}

dream({ async: false });
// prints: "text"

Extensibilité

Rappels

Grâce aux rappels, les utilisateurs de l'API peuvent écraser une certaine partie de votre code. Ouvrez certaines fonctions qui nécessitent une personnalisation dans des fonctions de rappel configurables, permettant aux utilisateurs de l'API de remplacer facilement votre code par défaut.

Une fois que l'interface API reçoit un rappel, assurez-vous de le documenter et de fournir des exemples de code.

Événements

Il est préférable de connaître le nom de l'interface des événements. Vous pouvez choisir librement le nom de l'événement pour éviter la duplication des noms avec les événements natifs.

Gestion des erreurs

Toutes les erreurs ne sont pas utiles aux développeurs pour déboguer le code :

// jQuery 允许这么写
$(document.body).on('click', {});

// 点击时报错
//   TypeError: ((p.event.special[l.origType] || {}).handle || l.handler).apply is not a function
//   in jQuery.min.js on Line 3

De telles erreurs sont difficiles à déboguer, alors ne faites pas perdre de temps aux développeurs. Dites-leur directement quelle erreur ils ont commise :

if (Object.prototype.toString.call(callback) !== '[object Function]') { // 看备注
  throw new TypeError("callback is not a function!");
}

Remarque : typeof callback === "function" posera des problèmes dans les anciens navigateurs et object sera traité comme un function .

Prévisibilité

Une bonne API est prévisible et les développeurs peuvent déduire son utilisation à partir d'exemples.

La détection de fonctionnalités de Modernizr est un exemple :

a) Elle utilise des noms d'attributs qui correspondent exactement aux concepts HTML5, CSS et API

b) Chaque détection individuelle est cohérente. Renvoyer vrai ou les fausses valeurs

// 所有这些属性都返回 'true' 或 'false'
Modernizr.geolocation
Modernizr.localstorage
Modernizr.webworkers
Modernizr.canvas
Modernizr.borderradius
Modernizr.boxshadow
Modernizr.flexbox

s'appuient sur des concepts que les développeurs connaissent déjà et qui peuvent être prévisibles.

La syntaxe des sélecteurs de jQuery est un exemple évident. Les sélecteurs CSS1-CSS3 peuvent être utilisés directement dans son moteur de sélection DOM.

$("#grid") // Selects by ID
$("ul.nav > li") // All LIs for the UL with class "nav"
$("ul li:nth-child(2)") // Second item in each list

Coordination proportionnelle

Une bonne API n'est pas forcément une petite API, la taille de l'API doit être proportionnée à ses fonctionnalités.

Par exemple, Moment.js, une bibliothèque bien connue d'analyse et de formatage de dates, peut être qualifiée d'équilibrée. Son API est à la fois concise et fonctionnelle.

Avec une bibliothèque spécifique à des fonctions comme Moment.js, il est important de garder l'API ciblée et petite.

Rédiger la documentation de l'API

L'une des tâches les plus difficiles du développement logiciel est de rédiger de la documentation. En fait, tout le monde déteste rédiger de la documentation. La plainte la plus courante est qu'il n'existe pas d'outil de documentation facile à utiliser. .

Voici quelques outils de génération automatique de documents :

  • YUIDoc (nécessite Node.js, npm)

  • JsDoc Toolkit (nécessite Node.js, npm)

  • Markdox (nécessite Node.js, npm)

  • Dox (nécessite Node.js, npm)

  • Docco (nécessite Node.js, Python, CoffeeScript)

  • JSDuck (nécessite Ruby, gem)

  • JSDoc 3 (nécessite Java)

Le plus important est : s'assurer que la documentation et le code sont mis à jour simultanément.

Références :

  • Bonne conception d'API

  • Concevoir de meilleures API JavaScript

  • Les secrets d'une superbe conception d'API JavaScript


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn