<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title></title>
		<description>enjoy code coding blog</description>		
		<link>https://s-petit.github.io</link>
		<atom:link href="https://s-petit.github.io/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Hibernate: Maîtrisez le débit et les performances de vos requêtes SQL</title>
				<description>&lt;p&gt;Dans ce post, j’aimerais vous parler de bonnes pratiques &lt;strong&gt;Hibernate&lt;/strong&gt;. Le sujet semble éculé, tant cette technologie existe depuis longtemps. Il existe déjà par ailleurs de nombreuses ressources permettant de bien comprendre le framework.&lt;/p&gt;

&lt;p&gt;Pourtant, en 2020, le sujet me semble encore d’actualité, car Hibernate est toujours massivement utilisé dans de nombreux projets Java. Et il est souvent mal utilisé.&lt;/p&gt;

&lt;p&gt;Une majorité des problèmes de performances que j’ai pu rencontrer dans ma carrière étaient liés à des interactions entre l’application et la base de données, et à une méconnaissance des bonnes pratiques Hibernate et SQL.&lt;/p&gt;

&lt;p&gt;De plus, c’est un fait, Hibernate est mal-aimé.&lt;/p&gt;

&lt;p&gt;Les développeurs trouvent l’outil difficile à configurer et maintenir. Les DBA constatent que les bases de données SQL sont sollicitées par des requêtes pouvant être superflues ou mal optimisées. Les devops aussi pourront déplorer une utilisation mémoire très importante et des temps de réponse médiocres sur les serveurs.&lt;/p&gt;

&lt;p&gt;Souvent, on rejette la faute à Hibernate. Il faut dire que l’outil est tellement puissant et flexible qu’il est vraiment très facile de prendre de mauvaises décisions qui vont dégrader considérablement les performances et la maintenabilité d’une application.&lt;/p&gt;

&lt;p&gt;Pourtant, avec quelques astuces à la portée de tous, on peut aisément atténuer la majorité des écueils les plus courants.&lt;/p&gt;

&lt;p&gt;Avec ma modeste expérience, je souhaiterais rappeler certains principes de base et démontrer que l’on peut utiliser Hibernate proprement, en contrôlant le flux et la qualité des requêtes générées, pour le plus grand bonheur de vos utilisateurs et de vos collègues.&lt;/p&gt;

&lt;h2 id=&quot;toujours-penser-sql-dabord&quot;&gt;Toujours penser SQL d’abord&lt;/h2&gt;

&lt;p&gt;Il est parfois bon de rappeler les choses évidentes. Hibernate ne fait pas de magie, il convertit du Java en SQL notamment avec la configuration effectuée dans des classes Java (les fameuses entités).&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:green&quot;&gt;La clé pour bien utiliser Hibernate, c’est toujours se préoccuper du SQL qui sera généré à la fin.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Lorsque vous travaillez sur une fonctionnalité, essayez d’imaginer les requêtes SQL minimales pour répondre au besoin.&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:red&quot;&gt;Si le SQL généré par Hibernate contient plus de requêtes ou d’instructions (champs, jointures, etc.) que nécessaire, alors votre configuration Hibernate n’est pas optimale.&lt;/span&gt; La base répondra moins rapidement, et vous polluerez votre heap JVM avec des objets inutiles.&lt;/p&gt;

&lt;p&gt;Comment éviter cela ? Les prochaines lignes vous apporteront quelques éléments de réponse.&lt;/p&gt;

&lt;h2 id=&quot;la-configuration-des-entités-hibernate&quot;&gt;La configuration des entités Hibernate&lt;/h2&gt;

&lt;p&gt;La plupart des problèmes liés à Hibernate proviennent d’une mauvaise configuration des entités. Le rôle d’une entité est de représenter en Java une table SQL et la stratégie pour la requêter. Le souci, c’est que la configuration de votre entité va impacter TOUTES les requêtes qui vont référencer cette entité. On a donc une configuration d’entité commune qui sera utilisée par des requêtes supposées être sur-mesure.&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:green&quot;&gt;Il faut donc configurer vos entités de façon la plus fermée et minimale possible, et aller chercher les infos supplémentaires au cas par cas dans vos requêtes.&lt;/span&gt;&lt;/p&gt;

&lt;h3 id=&quot;soyez-paresseux-&quot;&gt;Soyez paresseux !&lt;/h3&gt;

&lt;p&gt;La règle d’or à appliquer autant que possible, est de marquer explicitement toutes vos associations &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@OneToMany&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@ManyToOne&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@OneToOne&lt;/code&gt; comme étant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LAZY&lt;/code&gt;. La plupart des soucis de performance Hibernate sont provoqués par des jointures non maîtrisées, ce qui va générer des requêtes inutiles ou trop lourdes. Ce paramètre vous obligera à faire vos jointures uniquement quand elles seront nécessaires.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Entity&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Id&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@OneToOne&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LAZY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Department&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;department&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;span style=&quot;color:green&quot;&gt;C’est le conseil le plus important de cet article&lt;/span&gt;, car il offre des bénéfices considérables assez facilement.&lt;/p&gt;

&lt;p&gt;Cependant, l’appliquer sur un projet existant ne sera pas toujours simple car cela nécessitera de réécrire une partie des requêtes référençant cette entité (pour aller chercher manuellement les jointures). Si vous oubliez de le faire, le compilateur ne vous protégera pas et vous aurez des erreurs au runtime (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyInitializationException&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Cette exception peut être évitée avec l’option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enable_lazy_load_no_trans&lt;/code&gt;. Celle-ci permet de faire automatiquement une requête en base pour les associations &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LAZY&lt;/code&gt; qui ne sont pas encore dans la session Hibernate, au moment où elles seront appelées dans le code (ex: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;employee.getDepartment()&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:red&quot;&gt;Cependant, activer cette option reste déconseillée&lt;/span&gt;. Comme je l’ai dit, toute requête automatique non maitrisée sera souvent superflue et dégradera vos performances. Il est préférable que Hibernate jete une &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyInitializationException&lt;/code&gt; qui sera bien plus visible, et que vous pourrez gérer avec des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;join fetch&lt;/code&gt; dans vos requêtes HQL. Nous parlerons des requêtes HQL plus en détail ci-après.&lt;/p&gt;

&lt;p&gt;Cela dit, s’il faut choisir, il reste préférable d’utiliser l’option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LAZY + enable_lazy_load_no_trans&lt;/code&gt; plutôt que d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAGER&lt;/code&gt;. Cette option peut d’ailleurs s’avérer utile en cas de migration progressive de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EAGER&lt;/code&gt; vers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LAZY&lt;/code&gt; car il offre un compromis acceptable.&lt;/p&gt;

&lt;h3 id=&quot;autres-optimisations&quot;&gt;Autres optimisations&lt;/h3&gt;

&lt;p&gt;Hibernate propose beaucoup d’options pour affiner la configuration des entités. Certaines sont plus ou moins applicables selon le contexte. En voici deux faciles à appliquer :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Marquez comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Transient&lt;/code&gt; tous les champs et méthodes de l’entité qui ne doivent avoir aucune interaction avec la base de données. Il peut parfois être pratique de rajouter du comportement dans votre entité, mais cela ne doit pas impacter les requêtes vers la base.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Entity&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Id&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@OneToOne&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Department&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;department&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Transient&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getDepartmentName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;department&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Si vous avez des tables ou des champs en lecture seule, il est très intéressant d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Immutable&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insertable=false&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;updatable=false&lt;/code&gt;. Hibernate évitera d’envoyer des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UPDATE&lt;/code&gt; indésirables pas toujours évidents à détecter, tout en amélirant la lisibilité du code.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Entity&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Immutable&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Id&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Entity&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Id&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Column&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;department&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insertable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updatable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;department&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;la-responsabilité-des-entités-hibernate&quot;&gt;La responsabilité des entités Hibernate&lt;/h2&gt;

&lt;p&gt;Ce point est également essentiel, et n’est même pas spécifique a Hibernate : &lt;span style=&quot;color:green&quot;&gt;Limitez au maximum les responsabilités et le couplage des entités Hibernate avec vos autres composants&lt;/span&gt;. Une entité a pour rôle de représenter votre table, et rien d’autre. De plus, pour fonctionner, votre entité se doit de respecter certains prérequis (getters/setters, classe mutable…) qui ne sont pas souhaitables dans le reste de votre code.&lt;/p&gt;

&lt;p&gt;Pour cela il est primordial de ne pas réutiliser vos entités Hibernate au-delà de la couche de persistance. Convertissez-les le plus vite possible dans une classe dédiée. Sinon, il y aura un couplage fort entre la persistance, le métier ou encore la vue (API REST, templates HTML, etc.). &lt;span style=&quot;color:red&quot;&gt;Ne référencez jamais vos entités dans les couches de plus haut niveau !&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Même si cela peut être tentant pour éviter de la duplication, chaque fois que vous réutiliserez une entité pour des problématiques différentes (techniques ou métiers), vous risquez d’ajouter des données ou comportements spécifiques qui amèneront des risques de bugs sur vos autres fonctionnalités.&lt;/p&gt;

&lt;p&gt;Pour chaque use case, essayez autant que possible de créer des classes dédiées :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmployeeAgeDTO&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findEmployeeAge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employeeId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employeeRepository&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;employeeId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;EmployeeAgeDTO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBirthDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmployeeDepartmentDTO&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findEmployeeWithDepartment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employeeId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employeeRepository&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;employeeId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;EmployeeDepartmentDTO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDepartment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Votre entité Hibernate sera aussitôt consommée et convertie dans une structure minimale et donc optimale.&lt;/p&gt;

&lt;p&gt;Cela va amener un peu de duplication et vous devrez gérer la conversion entre vos classes, mais cela vous protègera de tout effet de bord non voulu (SQL ou Java). La partie conversion est souvent considérée comme laborieuse, mais reste peu complexe et donc peu coûteuse à maintenir.&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:red&quot;&gt;En revanche, si vous décidez d’utiliser des classes mutualisées, vous couplerez vos use cases ce qui fragilisera à terme la maintenabilité de votre code.&lt;/span&gt;&lt;/p&gt;

&lt;h2 id=&quot;les-requêtes-hql&quot;&gt;Les requêtes HQL&lt;/h2&gt;

&lt;p&gt;La dernière chose nécessaire pour avoir des résultats performants et sans effet de bord, est d’essayer, pour chaque nouveau besoin, de faire des requêtes sur-mesure. En effet, entre plusieurs fonctionnalités, les résultats et leur format seront forcément différents.&lt;/p&gt;

&lt;p&gt;De plus, la plupart du temps, vous n’aurez pas besoin de tous les champs de la table, ni de toutes ses associations.&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color:green&quot;&gt;Faire des &lt;a href=&quot;https://stackoverflow.com/questions/1031076/what-are-projection-and-selection&quot;&gt;projections&lt;/a&gt; sera souvent la meilleure solution.
De cette façon, chaque requête exprimera et cherchera uniquement ce dont elle a besoin.&lt;/span&gt; Les associations &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LAZY&lt;/code&gt; permettront d’éviter les jointures automatiques indésirables. Vous ne ferez des jointures seulement en cas de besoin.&lt;/p&gt;

&lt;p&gt;Le résultat de la projection sera donc une aggregation de plusieurs tables dans un format différent de celui de vos entités. Utiliser une classe dédiée sera donc nécessaire pour représenter ce résultat.&lt;/p&gt;

&lt;p&gt;Un exemple possible, qui instancie un DTO directement à partir de la requête :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EmployeeDto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findEmployeesByDepartment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;departmentName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EmployeeDto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessionFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCurrentSession&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createQuery&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;new com.mycompany.dto.EmployeeDto(employee.id, employee.name, department.name) &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;from Employee employee &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;join Department department on employee.departmentId = department.id &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;where department.name = :departmentName &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;order by employee.name&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmployeeDto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setParameter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;departmentName&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;departmentName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResultList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pour résumer, cet exemple regroupe une bonne partie des recommandations citées plus haut :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Une requête SQL totalement maîtrisée et avec des performances optimales.&lt;/li&gt;
  &lt;li&gt;On découple l’entité des résultats de la requête avec une classe dédiée (ici &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EmployeeDto&lt;/code&gt;). En instanciant la classe directement dans la requête vous n’aurez même pas besoin de faire la conversion en Java !&lt;/li&gt;
  &lt;li&gt;L’entité n’est pas exposée dans les couches métier / présentation de votre application qui ne pourront pas exploiter des champs ou des données inutiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;en-cas-de-doute-affichez-et-vérifiez-régulièrement-les-requêtes-sql-générées&quot;&gt;En cas de doute, affichez et vérifiez régulièrement les requêtes SQL générées&lt;/h2&gt;

&lt;p&gt;Pour mesurer et optimiser les requêtes SQL, il ne faut pas hésiter à les logger pendant vos phases de développement, en activant les options fournies (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show_sql&lt;/code&gt;, etc.) et en utilisant votre outil de log favori.&lt;/p&gt;

&lt;p&gt;Exemple avec &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logback&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;logger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;org.hibernate.SQL&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;level=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;DEBUG&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;logger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;org.hibernate.type&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;level=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;TRACE&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cela vous permettra notamment de savoir si le souci provient de Hibernate ou de la base. Dans le 2e cas de figure, rapprochez-vous de votre DBA pour faire de l’optimisation (index, vues, etc.)&lt;/p&gt;

&lt;h2 id=&quot;pensez-à-consulter-le-blog-de-vlad-mihalcea&quot;&gt;Pensez à consulter le blog de Vlad Mihalcea&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/vlad_mihalcea&quot;&gt;Vlad Mihalcea&lt;/a&gt; est une personne incontournable dans l’écosystème Hibernate. Il écrit énormément sur Hibernate notamment au travers de son &lt;a href=&quot;https://vladmihalcea.com&quot;&gt;blog&lt;/a&gt; très complet. Il est régulièrement mis à jour et honnêtement, j’ai toujours trouvé la réponse à mes questions.&lt;/p&gt;

&lt;p&gt;C’est simple, dès que j’ai un problème sur Hibernate, j’utilise mon moteur de recherche préféré et je suffixe toutes mes recherches par &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Vlad&lt;/code&gt; :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;one to many hibernate vlad&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;projection hibernate vlad&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vous serez alors redirigé vers son blog qui vous proposera forcément une réponse adaptée.&lt;/p&gt;

&lt;h2 id=&quot;un-outil-difficile-daccès-mais-qui-reste-très-pratique&quot;&gt;Un outil difficile d’accès mais qui reste très pratique&lt;/h2&gt;

&lt;p&gt;Soyons honnêtes, Hibernate requiert une certaine période d’apprentissage et certains de ses comportements par défaut peuvent faciliter une mauvaise utilisation. Son manque de cadre et sa flexibilité peuvent amener de la confusion et du découragement, surtout au début.&lt;/p&gt;

&lt;p&gt;Malgré tout, je pense que sa mauvaise réputation est un peu injuste car c’est un bon outil, puissant et customisable. Il permet de s’abstraire de la complexité liée a la couche JDBC et d’avoir moins de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boilerplate&lt;/code&gt; dans la couche de persistance de son code, tout en faisant du SQL propre.&lt;/p&gt;

&lt;p&gt;De plus, contrairement à ce que j’ai pu lire et entendre, Hibernate n’est pas incompatible avec des concepts comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DDD&lt;/code&gt; si on arrive à isoler correctement la partie Hibernate du reste du code métier. Il existe un bon nombre de stratégies et patterns pour y arriver : Utilisation des interfaces et de l’encapsulation, architecture hexagonale, isolation à partir de modules de votre outil de build (Maven/Gradle…).&lt;/p&gt;

&lt;p&gt;J’ajouterais même qu’il peut être complémentaire avec d’autres outils comme &lt;a href=&quot;https://www.jooq.org&quot;&gt;jOOQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avec ce billet, j’espère vous avoir convaincu que l’on peut réussir à maîtriser un minimum ce framework avec quelques ajustements basiques, sans pour autant être un expert.&lt;/p&gt;

&lt;p&gt;Bonne hibernation !&lt;/p&gt;

</description>
				<pubDate>Thu, 12 Nov 2020 00:00:00 +0000</pubDate>
				<link>https://s-petit.github.io/post/hibernate/</link>
				<guid isPermaLink="true">https://s-petit.github.io/post/hibernate/</guid>
			</item>
		
			<item>
				<title>Devenir parent en étant indépendant : Retour d&apos;expérience et optimisations fiscales</title>
				<description>&lt;p&gt;Dans cet article, je souhaiterais vous partager mon expérience d’indépendant et de jeune père de famille. Dans les deux situations, nous sommes confrontés quotidiennement à des situations inédites et apprenons énormément de nouvelles choses, souvent sur le tas. Cela a été évidemment le cas pour moi aussi.&lt;/p&gt;

&lt;p&gt;Si notre vécu de parent est souvent assez singulier, ce n’est pas le cas en ce qui concerne notre quotidien de travailleur indépendant, où nous sommes soumis aux mêmes règles, et vivons beaucoup de choses similaires. On peut donc légitimement se demander si ce choix de vie professionnelle est compatible avec cette nouvelle situation familiale ? Existe-t-il, à l’instar des salariés, des dispositifs ou des aides spécifiques à ce statut ?&lt;/p&gt;

&lt;p&gt;Il existe effectivement quelques aides et optimisations spécifiques à la famille et à la parentalité, qui nous permettent d’économiser de l’argent assez facilement. Aucun des cabinets comptable avec qui j’ai pu travailler ne m’avait parlé de ces spécificités. Je les ai donc connues soit par curiosité, soit par hasard.&lt;/p&gt;

&lt;p&gt;Après quelques discussions avec des confrères, je me suis rendu compte que mon cas n’était pas isolé, et que cela pouvait être intéressant de partager ces informations.&lt;/p&gt;

&lt;h2 id=&quot;congé-parental&quot;&gt;Congé parental&lt;/h2&gt;

&lt;p&gt;Peut-être que comme moi, vous avez choisi cette vie d’indépendant pour avoir plus de flexibilité dans votre travail et trouver un meilleur équilibre entre votre vie professionnelle et personnelle.&lt;/p&gt;

&lt;p&gt;J’ai eu le bonheur d’avoir un enfant en 2017, et en concertation avec la maman, j’ai décidé de poser un congé parental pour une durée indéterminée (qui a finalement duré 2 mois). Le but pour moi était de profiter de ces instants uniques dans une vie, mais aussi d’accompagner mon épouse dans cette découverte de la parentalité qui est non seulement difficile, mais qui, à mon sens, doit se partager a deux. La présence du papa est réellement importante tant pour le soutien moral, que pour les tâches quotidiennes qui deviennent de plus en plus nombreuses avec des enfants.&lt;/p&gt;

&lt;p&gt;C’est à ce moment-là que mon statut de freelance a pris tout son sens. Dans un pays encore en retard sur les législations liées au congé paternité pour les salariés, il permet une réelle souplesse dans la gestion de notre temps, malgré la contrepartie financière non négligeable liée aux absences sans solde.&lt;/p&gt;

&lt;p&gt;Même si on est en droit de se dire que l’aspect pécuniaire passe au second plan, il est tout de même judicieux d’anticiper cette pause pour atténuer la perte de revenus qui se répercutera forcément sur votre foyer et votre quotidien.&lt;/p&gt;

&lt;p&gt;Combien de temps consacrer pour ce congé ? Quel chiffre d’affaires viser pour garder un certain confort financier ? Est-il nécessaire de chercher une nouvelle mission en avance ?
Ce sera à vous de le déterminer, en élaborant un emploi du temps sur-mesure. Le reste ne sera qu’une formalité, car il est généralement assez aisé de suspendre son activité, même pour une durée prolongée, en s’arrangeant avec ses clients.&lt;/p&gt;

&lt;p&gt;Toute cette flexibilité fait la force de notre statut, malgré ce côté à double tranchant qui nécessite un peu d’anticipation de notre part. En outre, Il existe quelques aides et optimisations intéressantes relativement méconnues que je vais détailler ci-dessous.&lt;/p&gt;

&lt;h2 id=&quot;prime-de-paternité&quot;&gt;Prime de paternité&lt;/h2&gt;

&lt;p&gt;Cet article étant uniquement basé sur mon vécu, et ne voulant pas parler de choses que je ne connais pas, je ne vais malheureusement pas parler des droits concernant la maternité. Je vais me focaliser uniquement sur ce que j’ai pu expérimenter personnellement : La &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prime de paternité&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Avec un statut d’indépendant, le RSI (désormais intégré au régime général de la sécurité sociale) propose une indemnité forfaitaire pour tout père voulant s’absenter dans le cadre de la naissance d’un enfant (en 2020, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;56,35 € par jour&lt;/code&gt; sur un maximum de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;11 jours&lt;/code&gt;, donc au mieux &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;620 €&lt;/code&gt;). Cette indemnité compensera sans doute assez peu la perte financière liée a ce congé sans solde, mais cela reste toujours bon à prendre. Il suffit juste de faire valoir ce droit dans les 4 mois qui suivent la naissance de l’enfant en envoyant un formulaire et des pièces justificatives à votre caisse d’assurance maladie.&lt;/p&gt;

&lt;h3 id=&quot;sources-officielles&quot;&gt;Sources officielles:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ameli.fr/yvelines/assure/droits-demarches/famille/maternite-paternite-adoption/conge-paternite-accueil-enfant#text_9717&quot;&gt;Droit de congé paternité&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ameli.fr/yvelines/assure/remboursements/indemnites-journalieres/conge-paternite-accueil-enfant#text_114763&quot;&gt;Montant des indemnités journalières&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;chèques-cesu&quot;&gt;Chèques CESU&lt;/h2&gt;

&lt;p&gt;Comme la plupart des parents, vous aurez besoin de faire garder votre enfant. Lorsque vous devrez choisir une assistante maternelle agréée ou une crèche, vous aurez la possibilité, si celle-ci accepte, de payer en &lt;a href=&quot;https://travail-emploi.gouv.fr/droit-du-travail/les-contrats-de-travail/article/le-cheque-emploi-service-universel-cesu-prefinance&quot;&gt;chèque CESU préfinancé&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;L’avantage pour un indépendant, c’est que ces chèques pourront être achetés par la société. Jusqu’à un certain seuil (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1830 €&lt;/code&gt; par personne et par an en 2020), cela peut s’avérer très intéressant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour la société :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Le montant des chèques n’est pas soumis aux cotisations sociales (contrairement à de la rémunération)&lt;/li&gt;
  &lt;li&gt;L’achat des chèques est deductible du résultat (que ce soit en BNC ou en société)&lt;/li&gt;
  &lt;li&gt;Et surtout, cela donne droit a un credit d’impôt de 25 % : Le &lt;a href=&quot;https://www.service-public.fr/professionnels-entreprises/vosdroits/F31922&quot;&gt;credit d’impôt famille&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En revanche, le vendeur vous facturera des frais (autour de 100 € HT)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour vous :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Le montant des chèques compte comme un avantage en nature et non une rémunération. Ils ne seront pas soumis à l’impôt sur le revenu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cependant, ce montant ne sera pas inclus dans le calcul du &lt;a href=&quot;https://www.service-public.fr/particuliers/vosdroits/F8&quot;&gt;crédit d’impôt garde d’enfant&lt;/a&gt;. Mais cela vaut quand même largement le coup.&lt;/p&gt;

&lt;p&gt;Par rapport à de la rémunération, l’économie totale en taxes que vous allez réaliser sur ces 1830 € va dépendre de plusieurs facteurs (taux de cotisations, taux marginal d’imposition, etc.) mais pourra facilement dépasser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1000€&lt;/code&gt;, ce qui est très intéressant.&lt;/p&gt;

&lt;p&gt;De plus, vous pourrez bénéficier de cet avantage pour chaque nouvelle année civile. Par exemple, pendant 3 ans pour un enfant (jusqu’à l’entrée en maternelle). Vous pouvez également acheter des CESU dès lors que vous avez besoin de prestations de &lt;a href=&quot;https://www.servicesalapersonne.gouv.fr&quot;&gt;services à la personne&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un dernier conseil : Pour maximiser les chances de convaincre votre assistante maternelle d’accepter ce mode de paiement, il vaut mieux acheter des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CESU dématérialisés&lt;/code&gt;. 
Cela lui évitera de payer des frais supplémentaires ou de devoir encaisser elle-même les chèques physiques.&lt;/p&gt;

&lt;h3 id=&quot;sources-officielles-1&quot;&gt;Sources officielles:&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://travail-emploi.gouv.fr/droit-du-travail/les-contrats-de-travail/article/le-cheque-emploi-service-universel-cesu-prefinance&quot;&gt;Chèques CESU préfinancés&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;mutuelle&quot;&gt;Mutuelle&lt;/h2&gt;

&lt;p&gt;Cela ne se sait pas toujours, mais un travailleur indépendant a le droit de souscrire a une &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutuelle&lt;/code&gt; et d’en faire bénéficier son conjoint et ses enfants. Les avantages sont les suivants :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Mutualisation des coûts (un contrat unique coute souvent moins cher que la somme des autres contrats)&lt;/li&gt;
  &lt;li&gt;La part de cotisations du gérant (mais pas toujours celle de ses ayant-droits, cela dépend) est déductible des bénéfices (cf. la loi &lt;a href=&quot;https://www.impots.gouv.fr/portail/particulier/questions/je-cotise-un-contrat-madelin-quel-est-mon-avantage-fiscal&quot;&gt;Madelin&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Faire payer la société est toujours plus intéressant que de payer en tant que particulier : En effet, les sommes dépensées ne comptent pas comme de la rémunération et ne sont pas soumis a l’impôt sur le revenu (pour vous) ni aux cotisations sociales (pour la société). En effet, il faut toujours garder en tête que chaque virement de rémunération ou dividendes vers votre compte personnel sera soumis à ces fameuses taxes (qui oscillent entre 45 a 70 % selon votre situation). Vous économiserez donc potentiellement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plusieurs centaines d&apos;euros de taxes par an&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;C’est surtout intéressant si votre conjoint n’a pas de mutuelle ou si les garanties/cotisations de sa mutuelle employeur sont moins intéressants que la vôtre. Il/elle sera alors en droit de refuser la mutuelle de son employeur et vous pourrez l’inclure dans votre contrat.&lt;/p&gt;

&lt;h3 id=&quot;sources&quot;&gt;Sources:&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.loimadelin.com/les-contrats-madelin/mutuelle-madelin/&quot;&gt;Mutuelle Madelin&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;le-mot-de-la-fin&quot;&gt;Le mot de la fin&lt;/h2&gt;

&lt;p&gt;Se mettre à son compte, tout comme être parent est un apprentissage permanent où nous faisons de nombreuses erreurs que nous essayons de ne pas reproduire. Si j’ai pu connaître au bon moment et bénéficier pleinement de la &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prime de paternité&lt;/code&gt;, cela n’a pas été le cas avec les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chèques CESU&lt;/code&gt; et la &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutuelle collective&lt;/code&gt;. Avec cet article, j’espère pouvoir aider des confrères à ne pas reproduire les mêmes erreurs que moi, et indirectement profiter d’autant plus de leur vie familiale !&lt;/p&gt;

</description>
				<pubDate>Tue, 25 Aug 2020 00:00:00 +0000</pubDate>
				<link>https://s-petit.github.io/post/freelance-dad/</link>
				<guid isPermaLink="true">https://s-petit.github.io/post/freelance-dad/</guid>
			</item>
		
			<item>
				<title>Code Freelance, le livre qui démystifie le freelancing</title>
				<description>&lt;p&gt;Il y a quelques semaines de cela, Emilien Pecoul (&lt;a href=&quot;https://twitter.com/Ouarzy&quot;&gt;@Ouarzy&lt;/a&gt;), un développeur Lyonnais assez actif dans la communauté, a publié un livre consacré au freelancing :&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;fr&quot; dir=&quot;ltr&quot;&gt;Tu es &lt;a href=&quot;https://twitter.com/hashtag/Dev?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Dev&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/Freelance?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Freelance&lt;/a&gt; ou tu voudrais le devenir ? Je viens de publier un livre qui pourrait t&amp;#39;interesser! &lt;a href=&quot;https://twitter.com/hashtag/CodeFreelance?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#CodeFreelance&lt;/a&gt; &lt;a href=&quot;https://t.co/EVexVUW23r&quot;&gt;https://t.co/EVexVUW23r&lt;/a&gt; &lt;a href=&quot;https://t.co/3Yu5Anh2w5&quot;&gt;pic.twitter.com/3Yu5Anh2w5&lt;/a&gt;&lt;/p&gt;&amp;mdash; Emilien Pecoul (@Ouarzy) &lt;a href=&quot;https://twitter.com/Ouarzy/status/1166618626973212672?ref_src=twsrc%5Etfw&quot;&gt;August 28, 2019&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;br /&gt;
Étant moi-même indépendant depuis plus de 5 ans, ce livre a attisé ma curiosité. En effet, le sujet me passionne depuis longtemps et j’ai beaucoup étudié / expérimenté un certain nombre de ses aspects (Comptabilité, Fiscalité, Juridique…). 
Comme j’ai tenu ma comptabilité pendant 3 ans, j’avais justement fait un retour d’expérience lors d’un &lt;a href=&quot;https://twitter.com/HackYrJob/status/1060603392953847808&quot;&gt;meetup HackYourJob&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En achetant ce livre, je souhaitais non seulement soutenir la démarche que je trouve excellente pour aider à démystifier ce choix de vie encore trop méconnu, mais aussi pour comparer mon expérience avec celles d’un freelance chevronné et du collectif &lt;a href=&quot;https://www.hackyourjob.org&quot;&gt;HackYourJob&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avec cet article, je souhaite vous présenter brièvement les thèmes abordés dans cet ouvrage, et vous dire ce que j’en ai pensé. Et pourquoi pas aider certains indécis à décider de l’acheter ou non ?&lt;/p&gt;

&lt;h2 id=&quot;de-quoi-parle-ce-livre-exactement-&quot;&gt;De quoi parle ce livre exactement ?&lt;/h2&gt;

&lt;p&gt;Apres une introduction très pertinente expliquant pourquoi le freelancing progresse vite au travers d’un état des lieux du travail et du salariat aà l’heure actuelle, le livre passe dans le vif du sujet en traitant principalement des sujets suivants :&lt;/p&gt;

&lt;h3 id=&quot;pourquoi-le-statut-de-freelance-est-particulièrement-adapté-aux-développeurs-et-aux-métiers-de-lit&quot;&gt;Pourquoi le statut de freelance est particulièrement adapté aux développeurs et aux métiers de l’IT&lt;/h3&gt;

&lt;p&gt;En décrivant le marché du développement logiciel et ses limites actuelles, Emilien nous explique pourquoi les freelances y ont toute leur place et en quoi cette alternative est gagnant-gagnant, autant pour les développeurs que pour les entreprises clientes.&lt;/p&gt;

&lt;h3 id=&quot;quels-sont-les-avantages-et-motivations-qui-pourraient-nous-pousser-à-passer-à-notre-compte-et-quelles-sont-les-différences-par-rapport-au-salariat&quot;&gt;Quels sont les avantages et motivations qui pourraient nous pousser à passer à notre compte, et quelles sont les différences par rapport au salariat&lt;/h3&gt;

&lt;p&gt;Cette partie balaye un certain nombre d’idées reçues sur les freelances, et compare ce statut avec celui d’un salarié, notamment sur le plan pécuniaire.&lt;/p&gt;

&lt;h3 id=&quot;comment-opérer-sereinement-la-transition&quot;&gt;Comment opérer sereinement la transition&lt;/h3&gt;

&lt;p&gt;Ce chapitre distille de précieux conseils pour se lancer et se donner les moyens de réussir dans toutes les étapes de cette nouvelle aventure : démission, &lt;a href=&quot;https://www.definitions-marketing.com/definition/personal-branding/&quot;&gt;personal branding&lt;/a&gt;, négociation, etc.&lt;/p&gt;

&lt;h3 id=&quot;les-bases-juridiques-et-administratives-pour-gérer-son-entreprise&quot;&gt;Les bases juridiques et administratives pour gérer son entreprise&lt;/h3&gt;

&lt;p&gt;Cette partie plus technique que les autres est indispensable, car elle fournit quelques bases juridiques pour les entrepreneurs en herbe. Mais surtout, elle permet de réaliser que les connaissances nécessaires pour se lancer ne sont pas si compliquées et nombreuses que cela.&lt;/p&gt;

&lt;h3 id=&quot;comment-sépanouir-dans-son-métier&quot;&gt;Comment s’épanouir dans son métier&lt;/h3&gt;

&lt;p&gt;Equilibre professionnel / personnel, qualité de vie, organisation personnelle, veille technologique, réseautage, communautés et télétravail y sont ici abordés. 
Cette partie est sans doute la moins spécifique aux indépendants et peut concerner n’importe quel travailleur dans l’informatique. 
L’auteur nous partage ses conseils concernant notre recherche d’accomplissement personnel au travers de notre profession, mais pas seulement. 
En effet, la grande majorité des thèmes abordés sont des étapes selon moi indispensables pour être un bon professionnel.&lt;/p&gt;

&lt;p&gt;C’est probablement la partie la plus importante du livre. Car le freelancing est justement une des solutions possibles (mais pas la seule) permettant d’atteindre ce but.&lt;/p&gt;

&lt;h3 id=&quot;une-réflexion-sur-le-métier-de-développeur&quot;&gt;Une réflexion sur le métier de développeur&lt;/h3&gt;

&lt;p&gt;Pour finir, Emilien nous donne sa vision du métier de développeur à l’heure actuelle, et de ses limites. 
Manque de considération, préjugés, pression sociale, organisations pyramidales sont parmi les symptômes qui ankylosent notre secteur d’activité.
Il nous explique pourquoi le fait d’être à son compte permet de changer la donne et contribue à faire évoluer les mentalités.&lt;/p&gt;

&lt;h2 id=&quot;mon-avis&quot;&gt;Mon avis&lt;/h2&gt;

&lt;p&gt;Ne tournons pas autour du pot : J’ai beaucoup aimé.&lt;/p&gt;

&lt;p&gt;Cela dit, pour être honnête, il est probable que j’ai lu ce livre avec un &lt;a href=&quot;https://fr.wikipedia.org/wiki/Biais_de_confirmation&quot;&gt;biais de confirmation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sans le savoir, je me suis rendu compte au fur et à mesure de ma lecture, que Émilien et moi partagions beaucoup de valeurs sur le freelancing et le métier de développeur. 
Lire ce livre m’a conforté dans mes choix et donné de l’énergie pour essayer de faire encore mieux mon métier. La preuve, je relance ce blog qui n’avait pas bougé depuis 2 ans.&lt;/p&gt;

&lt;p&gt;Les chapitres se lisent bien, le style d’écriture est agréable. On sent que l’auteur a fait un travail énorme de vulgarisation et de synthèse. 
Le livre est donc complet et accessible, tout en restant assez court. Je l’ai fini après quelques heures de lecture, donc cela ne demande pas un gros investissement de temps. 
On se rend aussi compte qu’un gros effort a été fourni pour donner de la consistance aux arguments développés sur chaque thème abordé, ce qui rend le tout d’autant plus pertinent.&lt;/p&gt;

&lt;p&gt;Cependant, il faut savoir que le livre reste assez peu technique, notamment sur la partie entreprise.&lt;/p&gt;

&lt;p&gt;Les personnes qui cherchent à obtenir plus d’informations sur le statut à choisir pour leur activité (Le sempiternel débat EURL vs. SASU vs. les autres statuts) avec leurs avantages et inconvénients n’en trouveront pas pendant leur lecture.
De même, le livre ne contient pas d’astuces et avantages spécifiques aux indépendants, notamment sur la fiscalité et les régimes comme le RSI.&lt;/p&gt;

&lt;p&gt;Je pense que c’est un parti pris de l’auteur, qui ne voulait pas aller trop loin sur une partie extrêmement complexe, qui n’est pas son principal domaine d’expertise.&lt;/p&gt;

&lt;p&gt;Avec du recul, je me dis que ce n’était non plus l’objectif du livre, qui est de parler du freelancing dans sa globalité en tant que mode de vie tout en restant le plus accessible possible.
Les statuts et autres spécificités ne sont que des détails d’implémentation, dont le choix n’a finalement pas tant d’importance que cela.
Surtout qu’il existe des professionnels probablement plus compétents pour ce genre de conseils très techniques.&lt;/p&gt;

&lt;p&gt;Sur la partie entreprise également, un paragraphe est consacré au choix du nom de la structure. J’aurais trouvé intéressant d’aborder brièvement l’&lt;a href=&quot;https://www.inpi.fr/fr&quot;&gt;INPI&lt;/a&gt;, 
en tant que solution facultative, mais intéressante, pour protéger sa marque et s’assurer qu’il n’y a pas de collision avec une marque existante.&lt;/p&gt;

&lt;p&gt;Enfin, dans la partie qui parle de rémunération pour un &lt;a href=&quot;https://www.statutentreprise.com/travailleur-non-salarie/&quot;&gt;TNS&lt;/a&gt; en EURL, la part des cotisations sociales est
estimée à 30% environ. Je pense qu’il est intéressant de dire que ces cotisations sont généralement plus proches des 40% (les cotisations retraite de la CIPAV montent très vite), afin d’éviter de faire des estimations trop optimistes.&lt;/p&gt;

&lt;p&gt;Ces remarques n’engagent que moi, et ne concernent que quelques pages du livre. Ces petits détails n’altèrent en rien sa qualité intrinsèque.&lt;/p&gt;

&lt;h2 id=&quot;faut-il-acheter-ce-livre-&quot;&gt;Faut-il acheter ce livre ?&lt;/h2&gt;

&lt;p&gt;En conclusion, je pense que toute personne qui veut en savoir plus sur le freelancing peut acheter cet ouvrage les yeux fermés.
Il contient toutes les informations nécessaires pour aider et surtout rassurer ceux qui envisagent de sauter le pas.&lt;/p&gt;

&lt;p&gt;Je pense également que ce livre est totalement adapté pour n’importe quel travailleur dans l’informatique.
Les conseils et valeurs promulgués dans la plupart des chapitres sont tout à fait pertinents pour tout professionnel cherchant à s’améliorer et mieux vivre de son métier.&lt;/p&gt;

&lt;p&gt;Cela permet aussi de mieux comprendre les personnes qui ont décidé de se lancer, les motivations qui les animent, et que ce n’est pas toujours une question d’argent.&lt;/p&gt;

&lt;p&gt;Pour ceux qui sont déjà indépendants, cette lecture vous sera réconfortante, et vous aidera à déculpabiliser le cas échéant, quand certaines personnes vous perçoivent comme un mercenaire.&lt;/p&gt;

&lt;p&gt;Un grand merci à Emilien pour ce travail qui contribuera sans doute à l’évolution des mentalités, petit à petit !&lt;/p&gt;

</description>
				<pubDate>Fri, 13 Sep 2019 00:00:00 +0000</pubDate>
				<link>https://s-petit.github.io/post/review-code-freelance/</link>
				<guid isPermaLink="true">https://s-petit.github.io/post/review-code-freelance/</guid>
			</item>
		
			<item>
				<title>Programmation Fonctionnelle et Monads en Java</title>
				<description>&lt;p&gt;La programmation fonctionnelle (FP) a longtemps occupé une place relativement marginale dans le monde de l’entreprise, dominé par les langages impératifs (C, Java, C#, PHP…). Cependant depuis quelques années, ce paradigme de programmation se démocratise et gagne en popularité. Les projets en Scala se multiplient, et de nombreux langages impératifs traditionnels tels que Java ou Javascript s’enrichissent d’APIs se basant sur un certain nombre de concepts issus de la programmation fonctionnelle. Dans l’écosystème Java, la sortie du JDK 8 en 2014 et l’implémentation des lambdas a grandement contribué à populariser une composante majeure de la FP.&lt;/p&gt;

&lt;p&gt;L’ajout progressif de concepts de la FP dans nos bonnes vieilles applications d’entreprise est une très bonne chose, et se combine plutôt bien avec les langages orientés Objet (OOP). Manipuler des fonctions pures, favoriser la récursivité dans nos algorithmes, retarder l’évaluation des instructions ou encore manipuler des objects immutables favorise l’écriture de programmes plus propres et mieux optimisés tout en limitant les effets de bord.&lt;/p&gt;

&lt;h2 id=&quot;encourager-la-programmation-fonctionnelle-grâce-à-des-structures-dédiées&quot;&gt;Encourager la programmation fonctionnelle grâce à des structures dédiées&lt;/h2&gt;

&lt;p&gt;Lorsque l’on s’intéresse un peu a la FP et l’OOP, on finit par entendre parler des &lt;strong&gt;Monads&lt;/strong&gt; et de ses dérivées &lt;strong&gt;Functors&lt;/strong&gt; ou &lt;strong&gt;Applicatives&lt;/strong&gt;. Les Monads sont des structures de données répondant à un certain nombre de lois mathématiques (identité, associativité).&lt;/p&gt;

&lt;p&gt;Pour donner la définition la plus large possible d’une Monad, on peut dire que ce sont des structures de données, avec un &lt;strong&gt;contexte&lt;/strong&gt; et des comportements qui seront applicables sur les valeurs qu’elles encapsulent. Elles vont également permettre l’application et la composition de fonctions pures dans nos bons vieux langages impératifs orientés objets comme Java.&lt;/p&gt;

&lt;p&gt;Elles apportent un cadre qui va permettre d’encourager le développeur à bénéficier des forces de la FP, et ainsi de limiter au maximum les effets de bords classiques amenés notamment par des changements d’états ou des scopes de variables non judicieux.&lt;/p&gt;

&lt;p&gt;Par exemple, avec Optional de Java 8 (Spoiler : Optional est une représentation de la Monad &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Maybe&lt;/code&gt;) :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ici, notre instance d’Optional contient non seulement la valeur de ma String, mais propose un certain nombre de comportements supplémentaires. Selon le contexte, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getName()&lt;/code&gt; pourra contenir ou non une valeur.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les Monads permettent donc d’ajouter du contexte a des valeurs ou des objets, tout en permettant un certain nombre d’opérations fonctionnelles telles que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatMap&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orElse&lt;/code&gt;…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dans cet article, je ne vais pas m’épancher plus sur les règles et avantages de la programmation fonctionnelle, ou encore sur la définition et règles d’une Monad, car de nombreux excellents articles existent déja sur le sujet. Je vous invite d’ailleurs à consulter les articles dans la section &lt;a href=&quot;#bibliographie&quot;&gt;Bibliographie&lt;/a&gt; pour plus de détails.&lt;/p&gt;

&lt;h2 id=&quot;du-coup-quel-est-le-but-de-cet-article-&quot;&gt;Du coup, quel est le but de cet article ?&lt;/h2&gt;

&lt;p&gt;Une fois que l’on a plus ou moins compris la théorie, il peut être difficile de comprendre réellement comment et pourquoi les appliquer, notamment dans un langage comme Java. En effet, les Monads restent un concept, et ont un niveau d’abstraction assez élevé.&lt;/p&gt;

&lt;p&gt;Je vais donc tenter d’expliquer ce que peuvent apporter la FP et les Monads avec un cas pratique simple en Java, et pourquoi utiliser plus souvent ces pratiques dans nos développements au quotidien peut être intéressant.&lt;/p&gt;

&lt;p&gt;Cet exemple basique, partira d’une implémentation classique, puis nous y ajouterons progressivement des Functors, des Applicatives et enfin des Monads pour y exposer leurs bénéfices et leurs limites.&lt;/p&gt;

&lt;h2 id=&quot;cas-dutilisation&quot;&gt;Cas d’utilisation&lt;/h2&gt;

&lt;p&gt;L’exemple tournera autour d’une classe POJO &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item&lt;/code&gt;, qui représente un article d’un site ecommerce, avec son prix.&lt;/p&gt;

&lt;p&gt;Ce POJO sera implémenté avec des champs privés et des getters/setters pour tous les champs. Cette implémentation est pour moi un &lt;a href=&quot;https://fr.wikipedia.org/wiki/Code_smell&quot;&gt;code smell&lt;/a&gt; dans la plupart des cas (hors frameworks type Hibernate ou Jackson qui en ont besoin), mais elle est malheureusement la plus courante.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getCurrency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setCurrency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notre cas d’utilisation sera le suivant :&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;En tant que vendeur, je veux appliquer un prix promotionnel temporaire avec une reduction de 5$ et l’afficher sur ma page web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;exemple-dimplémentation-classique&quot;&gt;Exemple d’implémentation classique&lt;/h2&gt;

&lt;p&gt;Une implémentation classique pourrait être la suivante:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reduce_and_display_price_imperative_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//mutated Price instance&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;price: 45&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Le style du code utilisé dans cet exemple est volontairement grossier, mais malheureusement assez courant. Il y a bien d’autres facons d’implementer plus proprement ce cas d’utilisation.&lt;/p&gt;

&lt;p&gt;On y voit des code smells, tels que des instances qui ont muté alors que ce n’est pas necessaire, ou encore de la répétition (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;item.getPrice().getAmount()&lt;/code&gt;). En plus d’être améliorable, ce code est plus exposé aux bugs et divers effets de bords.&lt;/p&gt;

&lt;p&gt;Dans l’exemple suivant, je vais amener la notion de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Functor&lt;/code&gt;. Ce Functor va amener un contexte supplémentaire sur notre montant, et encourager l’utilisation de fonctions sur notre Item.&lt;/p&gt;

&lt;p&gt;Un Functor, c’est essentiellement une méthode &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmap&lt;/code&gt; (ou simplement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt;), qui va nous permettre d’appliquer des fonctions au sein de notre structure de données.&lt;/p&gt;

&lt;p&gt;Pour garder cet article le plus simple possible, nous allons utiliser un Functor volontairement minimaliste qui ne sait faire que des fmap : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyFunctor&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;functors&quot;&gt;Functors&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;Functor&lt;/strong&gt; en Java est une implémentation de cette interface :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@FunctionalInterface&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;F&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notre MyFunctor ressemble donc à ça…&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requireNonNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… Et va nous permettre de faire des traitements comme ceci :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reduce_and_display_price_functional_style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functor&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Item:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// we prevent Price mutation&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;price: 45&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Nous avons donc exactement le même résultat qu’avant, sauf que ce dernier a été calculé avec un enchaînement de fonctions pures.&lt;/p&gt;

&lt;p&gt;Nous bénéficions donc de la puissance de la FP (immutabilite, limitation des effets de bord, parallélisation, composition…) pour un code plus propre et moins exposé aux erreurs.&lt;/p&gt;

&lt;p&gt;Il est malgré tout important de préciser que de faire de la FP n’est pas une &lt;a href=&quot;https://fr.wikipedia.org/wiki/Balle_d%27argent#Sens_figur.C3.A9&quot;&gt;balle d’argent&lt;/a&gt;. Il est parfaitement possible de ne pas l’utiliser convenablement, et d’avoir des alternatives impératives bien meilleures. Mais je le répète, cela apporte un cadre qui encourage plus volontiers à adopter une approche plus propre et robuste.&lt;/p&gt;

&lt;p&gt;C’est exactement comme la classe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional&lt;/code&gt; de Java 8. Très controversée, elle est pourtant intéressante lorsqu’elle est utilisée judicieusement. Au contraire, une mauvaise utilisation peut faire bien pire que mieux.&lt;/p&gt;

&lt;p&gt;Cependant, les Functors montrent leurs limites, lorsque l’on souhaite mapper avec une fonction qui est elle-même boxée dans un Functor :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functors_cannot_fmap_on_functors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// we want our discount function to be wrapped into a functor &lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyFunctor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/*   String result = functor
                .fmap(Item::getPrice)
                .fmap(Item.Price::getAmount)
                .fmap(discount) // does not compile
                .fmap(p -&amp;gt; &quot;price: &quot; + p)
                .get();*/&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Could not map MyFunctor(50) with MyFunctor(amount -&amp;gt; amount - 5), only accepts simple Functions, but not boxed Functions&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cela ne compile pas. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmap&lt;/code&gt; n’acceptant que les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; simples, les Functors ne savent pas comment mapper appliquer une fonction boxée dans un Functor. C’est dommage, car &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function&lt;/code&gt; est un type Java comme les autres, et peut parfaitement être wrappé dans notre Functor pour profiter de son contexte.&lt;/p&gt;

&lt;h2 id=&quot;applicatives&quot;&gt;Applicatives&lt;/h2&gt;

&lt;p&gt;C’est à ce moment que les &lt;strong&gt;Applicatives&lt;/strong&gt; entrent en jeu. Grâce à leur méthode &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt;, Les Applicatives vont permettre d’appliquer des fonctions qui sont elles memes boxées dans un Applicative. Tout en gardant la puissance apportées par le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmap&lt;/code&gt; des Functors, car un &lt;strong&gt;Applicative est un Functor&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appFn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;// In an Applicative, T could be a Function&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requireNonNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;//applicative apply : A&amp;lt;T&amp;gt; -&amp;gt; A(T -&amp;gt; U) -&amp;gt; A&amp;lt;U&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appFn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;c1&quot;&gt;//appFn is an Applicative which contains a function&lt;/span&gt;
         &lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicativeFunction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appFn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;applicativeFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;//functor fmap : F&amp;lt;T&amp;gt; -&amp;gt; (T -&amp;gt; U) -&amp;gt; F&amp;lt;U&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;// fmap is a subset of apply&lt;/span&gt;
     &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
     &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Grâce aux Applicatives, nous allons pouvoir faire passer le test qui nous bloquait précédemment :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applicative_can_apply_boxed_functions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discountApplicative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// can also fmap because Applicative is a functor - fmap is a subset of apply.&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicative&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Item:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;discountApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;price: 45&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; acceptant en paramètre un Applicative, nous pouvons désormais y wrapper à loisir des valeurs et des fonctions, et les combiner. Cela commence à devenir intéressant ! Malheureusement, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; possède aussi sa limitation :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applicative_cannot_apply_on_functions_which_return_applicatives&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Applicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discountApplicative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// can also fmap because Applicative is a functor - fmap is a subset of apply.&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicative&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Item:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;discountApplicative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isNotEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;price: 45&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// result is like price: com.spe.applicative.MyApplicative@2a33fae&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Aie ! Dans notre test ci-dessus, on tente d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; sur un Applicative qui contient &lt;strong&gt;une fonction qui retourne un autre Applicative&lt;/strong&gt;. Cela compile, mais cela interrompt l’enchainement des fonctions, puisque les prochains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmap&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; seront appliqués sur un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Applicative&amp;lt;Integer&amp;gt;&lt;/code&gt; plutôt qu’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Integer&lt;/code&gt;.
Dans notre exemple, on pourrait s’en sortir avec un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;discountApplicative.get()&lt;/code&gt; mais la présence d’une méthode qui retourne la valeur brute contenue dans l’Applicative n’est pas toujours garanti et pertinent.&lt;/p&gt;

&lt;h2 id=&quot;monads&quot;&gt;Monads&lt;/h2&gt;

&lt;p&gt;Les &lt;strong&gt;Monads&lt;/strong&gt; sont la solution à tous nos problèmes :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// monads have 3 fundamental operations :&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// return : T1 -&amp;gt; M&amp;lt;T1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// unbox : M&amp;lt;T&amp;gt; -&amp;gt; T&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// bind : M&amp;lt;T&amp;gt; -&amp;gt; (T -&amp;gt; M&amp;lt;U&amp;gt;) -&amp;gt; M&amp;lt;U&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Monad unbox : M&amp;lt;T&amp;gt; -&amp;gt; T&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// monad bind : M&amp;lt;T&amp;gt; -&amp;gt; (T -&amp;gt; M&amp;lt;U&amp;gt;) -&amp;gt; M&amp;lt;U&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// a monad is a functor so it can also fmap&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;La méthode &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bind&lt;/code&gt; prend la valeur boxée et retourne une nouvelle Monad avec une nouvelle valeur boxée. A présent, nous allons pouvoir à loisir chaîner toutes les fonctions que l’on souhaite, même si celles-ci renvoient une Monad du même type ou bien des Monads covariantes.&lt;/p&gt;

&lt;p&gt;Nous allons illustrer ce comportement avec un Optional simplifié, avec 2 Monads : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyPresentMonad&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyEmptyMonad&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyOptionalMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyOptionalMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requireNonNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Monad return : T1 -&amp;gt; M&amp;lt;T1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Monad unbox : M&amp;lt;T&amp;gt; -&amp;gt; T&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// monad bind : M&amp;lt;T&amp;gt; -&amp;gt; (T -&amp;gt; M&amp;lt;U&amp;gt;) -&amp;gt; M&amp;lt;U&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// fmap is a subset of bind&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;andThen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyOptionalMonad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;INSTANCE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyEmptyMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Désormais, &lt;em&gt;sky is the limit&lt;/em&gt;. Notre test qui bloquait précédemment répond à notre besoin :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;monad_can_bind_on_other_monads_of_same_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discountFunction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// can also fmap because Monad is a functor - fmap is a subset of bind.&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monad&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Item:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;discountFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;price: 45&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Nous pouvons désormais appliquer des fonctions sur :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;des Functions simples&lt;/li&gt;
  &lt;li&gt;des Functions boxées dans des Monads&lt;/li&gt;
  &lt;li&gt;des Monads qui contiennent des Functions retournant une Monad du même type, et même des Monads covariantes !&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce dernier exemple, qui va renvoyer un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyEmptyMonad&lt;/code&gt;, l’illustre très bien :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;monad_can_bind_even_on_covariant_monads&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;book&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPresentMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;emptyFunction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;Monad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;emptyResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monad&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Item:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emptyFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emptyResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyEmptyMonad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Peu importe le type de fonction ou le type de Monad renvoyée, il est désormais possible d’appliquer les fonctions de notre choix, indépendamment du type de la Monad renvoyée.&lt;/p&gt;

&lt;h2 id=&quot;faites-plus-de-programmation-fonctionnelle-&quot;&gt;Faites plus de programmation fonctionnelle !&lt;/h2&gt;

&lt;p&gt;La programmation fonctionnelle prend de plus en plus de place, notamment en Java, et on comprend pourquoi.&lt;/p&gt;

&lt;p&gt;Au delà des lambdas, le JDK 8 propose son lot de Monads comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;. Elles possèdent leur contexte propre (présence ou non de valeur, gestion des collections avec évaluation paresseuse), et permettent d’y appliquer des fonctions indépendamment de leur type ou du résultat de la précédente opération. Notamment grâce aux méthodes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmap&lt;/code&gt; des Functors) et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bind&lt;/code&gt; des Monads), accompagnées d’opérations spécifiques à leur contexte propre (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifPresent&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orElse&lt;/code&gt; pour les Optional)&lt;/p&gt;

&lt;p&gt;Grâce à leur puissance et leur concision, ces 2 classes sont devenus incontournables pour les développeurs Java 8. Cela nous permet de réaliser à quel point il est intéressant de faire plus de programmation fonctionnelle et d’implémenter plus de Monads en Java.&lt;/p&gt;

&lt;p&gt;Sachant cela, et même si &lt;a href=&quot;#les-limites-de-java&quot;&gt;Java n’est pas le langage le plus adapté&lt;/a&gt; pour profiter au maximum du potentiel des Monads, il y a largement de quoi faire pour rendre notre code plus propre encore, et cela vous inspirera peut-être pour créer vos propres Functors/Applicatives/Monads pour les besoins de vos projets et ainsi faire profiter vos applications métier de leur puissance indéniable !&lt;/p&gt;

&lt;h2 id=&quot;bibliographie&quot;&gt;Bibliographie&lt;/h2&gt;

&lt;p&gt;Voici des articles que je recommande pour bien comprendre le sujet:&lt;/p&gt;

&lt;h3 id=&quot;les-functorsapplicativesmonads-expliqués-en-images&quot;&gt;Les Functors/Applicatives/Monads expliqués en images&lt;/h3&gt;

&lt;p&gt;en : &lt;a href=&quot;http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html&quot;&gt;http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;fr : &lt;a href=&quot;http://www.leonardmeyer.com/blog/2014/06/functors-applicatives-et-monads-en-images/&quot;&gt;http://www.leonardmeyer.com/blog/2014/06/functors-applicatives-et-monads-en-images/&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;mieux-comprendre-les-applicatives&quot;&gt;Mieux comprendre les Applicatives&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://pbrisbin.com/posts/applicative_functors/&quot;&gt;https://pbrisbin.com/posts/applicative_functors/&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;mieux-comprendre-les-monads&quot;&gt;Mieux comprendre les Monads&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://medium.com/@sinisalouc/demystifying-the-monad-in-scala-cc716bb6f534&quot;&gt;https://medium.com/@sinisalouc/demystifying-the-monad-in-scala-cc716bb6f534&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://scabl.blogspot.fr/2013/02/monads-in-scala-1.html&quot;&gt;http://scabl.blogspot.fr/2013/02/monads-in-scala-1.html&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;implémenter-des-monads-en-java&quot;&gt;Implémenter des Monads en Java&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://dzone.com/articles/functor-and-monad-examples-in-plain-java&quot;&gt;https://dzone.com/articles/functor-and-monad-examples-in-plain-java&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;les-limites-de-java&quot;&gt;Les limites de Java&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://jnape.com/the-perils-of-implementing-functor-in-java/&quot;&gt;http://jnape.com/the-perils-of-implementing-functor-in-java/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/35951818/why-can-the-monad-interface-not-be-declared-in-java&quot;&gt;https://stackoverflow.com/questions/35951818/why-can-the-monad-interface-not-be-declared-in-java&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://dzone.com/articles/whats-wrong-java-8-part-iv&quot;&gt;https://dzone.com/articles/whats-wrong-java-8-part-iv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.sitepoint.com/how-optional-breaks-the-monad-laws-and-why-it-matters/&quot;&gt;https://www.sitepoint.com/how-optional-breaks-the-monad-laws-and-why-it-matters/&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 01 Sep 2017 00:00:00 +0000</pubDate>
				<link>https://s-petit.github.io/post/fp-monads-java/</link>
				<guid isPermaLink="true">https://s-petit.github.io/post/fp-monads-java/</guid>
			</item>
		
	</channel>
</rss>