{"id":1066,"date":"2022-05-06T19:31:38","date_gmt":"2022-05-06T17:31:38","guid":{"rendered":"https:\/\/jagullo.fr\/blog\/?p=1066"},"modified":"2023-01-29T15:02:10","modified_gmt":"2023-01-29T14:02:10","slug":"le-design-pattern-fluent-interface-en-php","status":"publish","type":"post","link":"https:\/\/jagullo.fr\/blog\/le-design-pattern-fluent-interface-en-php\/","title":{"rendered":"Le design pattern Fluent Interface en php"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Le cha\u00eenage des m\u00e9thodes pour un code plus concis<\/h2>\n\n\n\n<p>Le design pattern <strong>Fluent Interface<\/strong> est beaucoup utilis\u00e9 si on vient du monde JavaScript avec la librairie jQuery. C&rsquo;est peut-\u00eatre cette librairie qui a d\u00e9mocratis\u00e9 ce patron de conception dans le d\u00e9veloppement web. Elle consiste \u00e0 ajouter \u00e0 chaque m\u00e9thode d&rsquo;une classe ou d&rsquo;un objet le fait de renvoyer la classe afin d&rsquo;utiliser plusieurs m\u00e9thodes&nbsp;\u00e0 partir d&rsquo;un m\u00eame appel. L&rsquo;objectif principal est d&rsquo;avoir un code plus concis et plus facile \u00e0 lire. <\/p>\n\n\n\n<p>Cependant avec ce syst\u00e8me les m\u00e9thodes <strong>ne peuvent plus renvoyer de valeur de contr\u00f4le<\/strong> comme true ou false afin de v\u00e9rifier le bon fonctionnement du programme. Ce patron de conception est \u00e0 utiliser sur les m\u00e9thodes ne devant pas renvoyer des donn\u00e9es comme les setters ou sur les m\u00e9thodes ne n\u00e9cessitant pas de v\u00e9rification. Il ne faut pas l&rsquo;utiliser si la m\u00e9thode doit par exemple envoyer un email afin de retourner true ou false si l&#8217;email est bien envoy\u00e9. Chaque programmeur doit bien r\u00e9fl\u00e9chir \u00e0 l&rsquo;impl\u00e9mentation de ce design pattern dans les classes pour ne pas provoquer l&rsquo;effet inverse en rendant le code plus compliqu\u00e9.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2022\/05\/illustration_fluent-php.jpg\" alt=\"Le design pattern Fluent Design permet d'\u00e9crire du code plus concis\" class=\"wp-image-1079\" width=\"720\" height=\"480\" srcset=\"https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2022\/05\/illustration_fluent-php.jpg 960w, https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2022\/05\/illustration_fluent-php-300x200.jpg 300w, https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2022\/05\/illustration_fluent-php-768x512.jpg 768w\" sizes=\"(max-width: 720px) 100vw, 720px\" \/><figcaption class=\"wp-element-caption\">Le design pattern Fluent Design pour un code plus concis<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Exemple d&rsquo;un cha\u00eenage de m\u00e9thodes en PHP<\/h2>\n\n\n\n<p>L&rsquo;exemple ci-dessous en PHP pr\u00e9sente une simple <strong>classe Person<\/strong> qui affiche le nom complet apr\u00e8s avoir enregistr\u00e9 le nom et le pr\u00e9nom. Les 2 fonctions <strong>setFirstName<\/strong> et <strong>setLastName<\/strong> utilisent le cha\u00eenage de m\u00e9thodes en renvoyant \u00e0 chaque fois la classe Person. Cette fa\u00e7on d&rsquo;\u00e9crire le code permet d&rsquo;appeler ces m\u00e9thodes sur le m\u00eame objet.<\/p>\n\n\n\n<pre class=\"wp-block-code language-php\"><code>&lt;?php\nclass Person {\n    private string $firstname = '';\n    private string $lastname = '';\n    public function setFirstName(string $value):Person {\n        $this-&gt;firstname = $value;\n        return $this;\n    }\n    public function setLastName(string $value):Person {\n        $this-&gt;lastname = $value;\n        return $this;\n    }\n    public function getName():string {\n        return $this-&gt;firstname . ' ' . $this-&gt;lastname;\n    }\n}\n$person = new Person();\n$person-&gt;setFirstName('Franck')-&gt;setLastName('Thilliez');\necho $person-&gt;getName(); \/\/ Franck Thilliez<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Optimisation du Fluent Interface en PHP<\/h2>\n\n\n\n<p>En PHP comme dans d&rsquo;autres langages de programmation, il est possible d&rsquo;appeler <strong>les propri\u00e9t\u00e9s d&rsquo;une classe de fa\u00e7on dynamique<\/strong>. Les d\u00e9veloppeurs PHP peuvent optimiser leurs codes en cr\u00e9ant un setter personnalis\u00e9 fonctionnant avec le principe du cha\u00eenage de m\u00e9thode. L&rsquo;exemple ci-dessous permet d&rsquo;optimiser le nombre de m\u00e9thodes dans la classe Person gr\u00e2ce \u00e0 une fonction setter globale qui enregistre les propri\u00e9t\u00e9s si elles existent.<\/p>\n\n\n\n<pre class=\"wp-block-code language-php\"><code>&lt;?php\nclass Person {\n    private string $firstname = '';\n    private string $lastname = '';\n    public function set(string $name, $value):Person {\n        if (isset($this-&gt;$name)) {\n            $this-&gt;$name = $value;\n        }\n        return $this;\n    }\n    public function getName():string {\n        return $this-&gt;firstname . ' ' . $this-&gt;lastname;\n    }\n}\n$person = new Person();\n$person-&gt;set('firstname', 'Olivier')-&gt;set('lastname', 'Norek');\necho $person-&gt;getName(); \/\/ Olivier Norek<\/code><\/pre>\n\n\n\n<p>Malheureusement il n&rsquo;est pas possible d&rsquo;utiliser <strong>la m\u00e9thode magique __set<\/strong> de PHP pour cr\u00e9er un cha\u00eenage de m\u00e9thode. En effet la d\u00e9finition de cette derni\u00e8re oblige \u00e0 renvoyer void ce qui emp\u00eache l&rsquo;utilisation du design pattern Fluent Interface. Mais il est tout \u00e0 fait possible de cr\u00e9er ses propres <strong>getter<\/strong> et <strong>setter<\/strong> pour exploiter les donn\u00e9es de la classe. Dans l&rsquo;exemple ci-dessous le getter utilise la nouvelle instruction <strong>match<\/strong> apparu en PHP 8 similaire au <strong>switch<\/strong> mais avec comme principale particularit\u00e9 qu&rsquo;elle renvoie une valeur.<\/p>\n\n\n\n<pre class=\"wp-block-code language-php\"><code>&lt;?php\nclass Person {\n    private array $data = &#91;];\n    public function set(string $name, $value):Person {\n        $this-&gt;data&#91;$name] = $value;\n        return $this;\n    }\n    public function get(string $name):?string {\n        return match ($name) {\n            'fullname'  =&gt; $this-&gt;data&#91;'firstname'] . ' ' . $this-&gt;data&#91;'lastname'],\n            default     =&gt; null\n        };\n    }\n}\n$person = new Person();\n$person-&gt;set('firstname', 'C\u00e9dric')-&gt;set('lastname', 'Sire');\necho $person-&gt;get('fullname'); \/\/ C\u00e9dric Sire<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Un design pattern exploitable dans tous les langages<\/h2>\n\n\n\n<p>Le design pattern Fluent Interface peut s&rsquo;utiliser <strong>dans tous les langages de programmation<\/strong>. En JavaScript on peut utiliser ce patron de conception exactement de la m\u00eame fa\u00e7on qu&rsquo;en PHP. L&rsquo;exemple JavaScript ci-dessous reprend la m\u00eame classe Person que dans l&rsquo;exemple PHP afin de reproduire ce patron de conception.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>class Person {\n    data = &#91;];\n    set(name, value) {\n        this.data&#91;name] = value\n        return this\n    }\n    get(name) {\n        switch (name) {\n            case 'fullname':\n                return this.data&#91;'firstname'] + ' ' + this.data&#91;'lastname']\n            default:\n                return null\n        }\n    }\n}\nlet author = new Person();\nauthor.set('firstname', 'Michael').set('lastname', 'Connelly');\nconsole.log(author.get('fullname')); \/\/ Michael Connelly<\/code><\/pre>\n\n\n\n<p>Le design pattern <strong>Fluent Interface<\/strong> permet de rendre son code source plus concis pour le d\u00e9veloppement. C&rsquo;est un patron de conception tr\u00e8s utilis\u00e9 par les d\u00e9veloppeurs web qui a \u00e9t\u00e9 d\u00e9mocratis\u00e9 par la librairie jQuery. Pour plus d&rsquo;informations, il y a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fluent_interface\" target=\"_blank\" rel=\"noreferrer noopener\">la page Wikip\u00e9dia<\/a> qui contient de nombreux exemples dans diff\u00e9rents langages de programmation C#, Java, Python, etc. <\/p>\n\n\n\n<link rel=\"stylesheet\" href=\"\/blog\/wp-content\/themes\/Extra-child\/assets\/css\/prism.css\">\n<script src=\"\/blog\/wp-content\/themes\/Extra-child\/assets\/js\/prism.js\"><\/script>\n<div class=\"list-tags\"><a href=\"https:\/\/jagullo.fr\/blog\/tag\/design-pattern\/\" class=\"link-tag\" title=\"Design Pattern\">Design Pattern<\/a><a href=\"https:\/\/jagullo.fr\/blog\/tag\/jquery\/\" class=\"link-tag\" title=\"jQuery\">jQuery<\/a><a href=\"https:\/\/jagullo.fr\/blog\/tag\/php\/\" class=\"link-tag\" title=\"PHP\">PHP<\/a><\/div>","protected":false},"excerpt":{"rendered":"<p>Le cha\u00eenage des m\u00e9thodes pour un code plus concis Le design pattern Fluent Interface est beaucoup utilis\u00e9 si on vient du monde JavaScript avec la librairie jQuery. C&rsquo;est peut-\u00eatre cette librairie qui a d\u00e9mocratis\u00e9 ce patron de conception dans le d\u00e9veloppement web. Elle consiste \u00e0 ajouter \u00e0 chaque m\u00e9thode d&rsquo;une classe ou d&rsquo;un objet le [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1079,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[8],"tags":[26,38,27],"class_list":["post-1066","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developpement","tag-design-pattern","tag-jquery","tag-php","et-has-post-format-content","et_post_format-et-post-format-standard"],"_links":{"self":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/1066","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/comments?post=1066"}],"version-history":[{"count":3,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/1066\/revisions"}],"predecessor-version":[{"id":2954,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/1066\/revisions\/2954"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/media\/1079"}],"wp:attachment":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/media?parent=1066"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/categories?post=1066"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/tags?post=1066"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}