{"id":2485,"date":"2020-08-16T23:18:24","date_gmt":"2020-08-16T21:18:24","guid":{"rendered":"https:\/\/devportfolio.net\/wp-dev-blog\/?p=2485"},"modified":"2020-08-16T23:18:24","modified_gmt":"2020-08-16T21:18:24","slug":"ui5-singleton","status":"publish","type":"post","link":"https:\/\/devportfolio.net\/wp-dev-blog\/ui5-singleton\/","title":{"rendered":"UI5 Singleton"},"content":{"rendered":"\n<p>Dans mes projets UI5 j&rsquo;utilise tr\u00e8s souvent le pattern singleton pour centraliser les appels backend et plus g\u00e9n\u00e9ralement pour organiser le code de mani\u00e8re coh\u00e9rente ce qui augmente la lisibilit\u00e9 et la maintenabilit\u00e9 de la solution. <\/p>\n\n\n\n<p>Dans mon dernier projet j&rsquo;ai par exemple cr\u00e9\u00e9 un fichier <code>FirebaseService.js<\/code> pour g\u00e9rer tous mes appels vers le service de d\u2019authentification de Firebase. La gestion des erreurs et l&rsquo;affichage d&rsquo;un loader li\u00e9s aux appels vers Firebase sont centralis\u00e9s et g\u00e9r\u00e9s dans cet objet. <\/p>\n\n\n\n<p>Le Singleton est un objet litt\u00e9ral contenant des m\u00e9thodes et des attributs qui sont regroup\u00e9s parce qu&rsquo;ils sont en quelque sorte li\u00e9s. La d\u00e9finition traditionnelle du mod\u00e8le singleton d\u00e9crit une classe qui ne peut \u00eatre instanci\u00e9e qu&rsquo;une seule fois et est accessible via un point d&rsquo;acc\u00e8s bien connu, par convention la m\u00e9thode <code>getInstance()<\/code>. Ci-dessous le mod\u00e8le de d\u00e9finition que j&rsquo;utilise dans mes projets :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">sap.ui.define([\n\t\"sap\/ui\/base\/Object\"\n], function (Object) {\n\t\"use strict\";\n\n\tvar _oInstance = null;\n\n\t\/** \n\t * Cet objet est un Singleton \n\t * \n\t * @see {@link }\n\t *\n\t * @author \n\t * @version 0.1\n\t *\n\t * @public\n\t *\/\n\tvar MySingleton = Object.extend(\"fr.dev.portfolio.MySingleton\", {\n\n\t\t__oMyVar: null,\n\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\t\t\/\/\tCONSTRUCTOR\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\t\tconstructor: function () {\n\t\t\tthis.__oMyVar = \"Attribut de classe priv\u00e9\";\n\t\t},\n\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\t\t\/\/\tMETHODS\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\t\t\/**\n\t\t * M\u00e9thode de classe\t \n\t\t * \n\t\t * @param {} xxx \n\t\t * @public\n\t\t *\/\n\t\tmethod_1: function () {\n\t\t\tthis.__oMyVar = \"Attribut de classe priv\u00e9 modifi\u00e9\";\n\t\t}\n\n\t});\n\n\treturn {\n\n\t\tgetInstance: function () {\n\t\t\tif (!_oInstance) {\n\t\t\t\t_oInstance = new Loader();\n\t\t\t}\n\t\t\treturn _oInstance;\n\t\t}\n\t};\n});<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Exemple avec une classe Util.Loader<\/h2>\n\n\n\n<p>Il arrive parfois que les appels backend prennent un moment pour se charger compl\u00e8tement. Une solution courante est d&rsquo;utiliser une animation (un loader) pour informer le visiteur que le site est en cours de chargement et qu&rsquo;une r\u00e9ponse va s\u2019afficher sous peu.<\/p>\n\n\n\n<p>Pour illustrer l&rsquo;utilisation d&rsquo;un Singleton dans ce cas, j&rsquo;ai cr\u00e9\u00e9 une classe <code>Loader<\/code> dans un namespace <code>Util<\/code> qui fourni une interface simple pour ajouter ou supprimer un loader dans l&rsquo;application : <\/p>\n\n\n\n<pre title=\"Ajouter le loader dans l'application \" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">Loader.getInstance().open()<\/code><\/pre>\n\n\n\n<pre title=\"Supprimer le loader\" class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">Loader.getInstance().close()<\/code><\/pre>\n\n\n\n<p>Une seule instance de la classe Loader peut exister dans l&rsquo;application, pas de risque de cr\u00e9er plusieurs loader inutilement.  <\/p>\n\n\n\n<p>Pour simplifier l&rsquo;exemple, j&rsquo;ai encapsul\u00e9 le contr\u00f4le utilisateur <code><a rel=\"noreferrer noopener\" href=\"https:\/\/openui5.hana.ondemand.com\/api\/sap.m.BusyDialog\" target=\"_blank\">BusyDialog<\/a><\/code> pour ajouter\/supprimer un loader. Mais il sera tr\u00e8s simple de modifier l&rsquo;animation du loader sur l&rsquo;enti\u00e8ret\u00e9 de l&rsquo;application \u00e0 l&rsquo;aide d&rsquo;un loader personnalis\u00e9 ou d&rsquo;une librairie javascript tiers en modifiant le code du Singleton . On r\u00e9duit les d\u00e9pendances avec l&rsquo;objet <a rel=\"noreferrer noopener\" href=\"https:\/\/openui5.hana.ondemand.com\/api\/sap.m.BusyDialog\" target=\"_blank\"><code>BusyDialog<\/code><\/a>, ainsi on gagne en flexibilit\u00e9 pour les \u00e9volutions futures.   <\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">sap.ui.define([\n\t\"sap\/ui\/base\/Object\",\n\t\"sap\/m\/BusyDialog\"\n], function (Object, BusyDialog) {\n\t\"use strict\";\n\n\tvar _oInstance = null;\n\n\t\/** \n\t * Ajouter\/supprimer un loader\n\t * \n\t * @see {@link https:\/\/openui5.hana.ondemand.com\/api\/sap.m.BusyDialog}\n\t *\n\t * @author devportoflio\n\t * @version 0.1\n\t *\n\t * @public\n\t *\/\n\tvar Loader = Object.extend(\"blog.devportfolio.demo.Loader\", {\n\n\t\t__loader: null,\n\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\t\t\/\/\tCONSTRUCTOR\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\t\tconstructor: function () {\n\t\t\tthis.__loader = new BusyDialog();\n\t\t},\n\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\t\t\/\/\tMETHODS\n\t\t\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\t\t\/**\n\t\t * \n\t\t * \n\t\t * @param {} xxx \n\t\t * @public\n\t\t *\/\n\t\topen: function () {\n\t\t\tthis.__loader.open();\n\t\t},\n\n\t\t\/**\n\t\t * \n\t\t * \n\t\t * @param {} xxx \n\t\t * @public\n\t\t *\/\n\t\tclose: function () {\n\t\t\tthis.__loader.close();\n\t\t}\n\n\t});\n\n\treturn {\n\n\t\tgetInstance: function () {\n\t\t\tif (!_oInstance) {\n\t\t\t\t_oInstance = new Loader();\n\t\t\t}\n\t\t\treturn _oInstance;\n\t\t}\n\t};\n});<\/code><\/pre>\n<\/div><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Le Singleton fournit un moyen de regrouper le code dans une unit\u00e9 logique qui peut \u00eatre accessible via une seule variable. En s&rsquo;assurant qu&rsquo;il n&rsquo;y a qu&rsquo;une seule copie d&rsquo;un objet singleton, vous savez que tout votre code utilise la m\u00eame ressource globale.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans mes projets UI5 j&rsquo;utilise tr\u00e8s souvent le pattern singleton pour centraliser les appels backend et plus g\u00e9n\u00e9ralement pour organiser le code de mani\u00e8re coh\u00e9rente ce qui augmente la lisibilit\u00e9 et la maintenabilit\u00e9 de la solution. Dans mon dernier projet j&rsquo;ai par exemple cr\u00e9\u00e9 un fichier FirebaseService.js pour g\u00e9rer tous mes appels vers le service [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55],"tags":[],"class_list":["post-2485","post","type-post","status-publish","format-standard","hentry","category-ui5"],"_links":{"self":[{"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/posts\/2485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/comments?post=2485"}],"version-history":[{"count":30,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/posts\/2485\/revisions"}],"predecessor-version":[{"id":2525,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/posts\/2485\/revisions\/2525"}],"wp:attachment":[{"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/media?parent=2485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/categories?post=2485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devportfolio.net\/wp-dev-blog\/wp-json\/wp\/v2\/tags?post=2485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}