{"id":485,"date":"2021-11-08T16:34:59","date_gmt":"2021-11-08T16:34:59","guid":{"rendered":"https:\/\/www.louismarchand.me\/?page_id=485"},"modified":"2021-11-09T19:00:27","modified_gmt":"2021-11-09T19:00:27","slug":"objet2-le-design-par-contrats","status":"publish","type":"page","link":"https:\/\/www.louismarchand.me\/index.php\/objet2-le-design-par-contrats\/","title":{"rendered":"Le \u00ab\u00a0design\u00a0\u00bb par contrats"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>En programmation orient\u00e9e par objets, le secret permettant de cr\u00e9er des classes robustes et le plus possible r\u00e9utilisables possible est de s&rsquo;assurer de garder une grande rigueur dans la programmation de ces classes. Cette rigueur passe par plusieurs \u00e9l\u00e9ments comme s&rsquo;assurer de bien comprendre le code de nos classes, bien documenter ces derni\u00e8res et respecter un standard stable qui permet de garantir au maximum la clart\u00e9 du code.<\/p>\n<p>L&rsquo;\u00e9l\u00e9ment que le \u00ab\u00a0design\u00a0\u00bb par contrats mets de l&rsquo;avant est de s&rsquo;assurer que le code que nous faisons soit bien compris (autant par le cr\u00e9ateur de la classe que pour l&rsquo;utilisateur de la classe). En fait, les contrats permettent de s&rsquo;assurer que l\u2019on comprend, en plus de ce que le code fait, ce que le code ne fait pas. Ils permettent de mettre en \u00e9vidence les limites du code de nos classes. De plus, les contrats permettent de s&rsquo;assurer que les utilisateurs de nos classes (que ce soit nous-m\u00eames ou d&rsquo;autres programmeurs) comprennent le mieux possible les m\u00e9canismes de ces classes.<\/p>\n<h2>Qu&rsquo;est-ce qu&rsquo;un contrat<\/h2>\n<p>La d\u00e9finition d&rsquo;un contrat est tr\u00e8s simple. C&rsquo;est un indicatif permettant de savoir certains \u00e9l\u00e9ments qui doivent toujours \u00eatre vrai dans un contexte pr\u00e9cis de la classe. Pour ceux qui ont d\u00e9j\u00e0 utilis\u00e9 ce type de m\u00e9canisme de langage, un contrat est en fait un type structur\u00e9 d&rsquo;assertion de code (plus d&rsquo;informations sur les assertions de code <a href=\"https:\/\/en.wikipedia.org\/wiki\/Assertion_(software_development)\">ici<\/a>).<\/p>\n<p>Pour donner une description plus compl\u00e8te, un contrat peut \u00eatre d\u00e9fini par tous les \u00e9l\u00e9ments suivants:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Indications permettant de d\u00e9finir ce qui doit \u00eatre vrai \u00e0 un certain moment dans le code;<\/li>\n<li>Permet de documenter le code;<\/li>\n<li>Permet au compilateur et au d\u00e9bogueur de savoir l&rsquo;intention du d\u00e9veloppeur;<\/li>\n<li>Permet de diriger les tests.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>L&rsquo;utilit\u00e9 des contrats est, entre autres,  de:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Diminuer les bogues;<\/li>\n<li>Faciliter la r\u00e9utilisation de code;<\/li>\n<li>Documenter les classes;<\/li>\n<li>Augmenter l&rsquo;efficacit\u00e9 des tests;<\/li>\n<li>Faciliter la maintenance du logiciel;<\/li>\n<li>etc.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>De plus, un des gros avantages de l&rsquo;approche par contrats est qu&rsquo;il permet de palier \u00e0 certaines probl\u00e9matiques d&rsquo;autres langages ont au niveau du principe objets. Par exemple, les langages bas\u00e9s sur C++ (incluant Java et C#) prot\u00e8gent l&rsquo;int\u00e9grit\u00e9 interne des classes en utilisant la port\u00e9e priv\u00e9e des m\u00e9thodes et des attributs. Comme nous l&rsquo;avons vu dans une th\u00e9orie pr\u00e9c\u00e9dente, la port\u00e9e priv\u00e9e va \u00e0 l&rsquo;encontre du principe objet puisque les enfants des classes n&rsquo;ont pas acc\u00e8s \u00e0 l&rsquo;enti\u00e8ret\u00e9 des m\u00e9thodes et attributs que ces classes parentes ont acc\u00e8s. Les contrats permettent une robustesse des classes similaires \u00e0 la port\u00e9e priv\u00e9e (en fait meilleur en g\u00e9n\u00e9ral), mais tout en respectant parfaitement le principe objets, puisque les contrats des parents s&rsquo;appliquent toujours \u00e0 l&rsquo;enti\u00e8ret\u00e9 des enfants.<\/p>\n<p>Il y a plusieurs sortes de contrats. Ceux qui nous int\u00e9resseront dans ce cours sont les trois (3) types de contrats suivants: les pr\u00e9conditions, les postconditions et les invariants.<\/p>\n<h2>Les pr\u00e9conditions<\/h2>\n<p>Une pr\u00e9condition est un contrat ajout\u00e9 \u00e0 une routine qui permet de valider l&rsquo;\u00e9tat de la classe avant l&rsquo;ex\u00e9cution de la routine ou de valider les arguments de la cette derni\u00e8re afin de s&rsquo;assurer qu&rsquo;elle s&rsquo;ex\u00e9cute correctement. On note les pr\u00e9conditions dans la clause \u00ab\u00a0require\u00a0\u00bb d&rsquo;une m\u00e9thode. Voici un exemple utilisant des pr\u00e9conditions.<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">make<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"c1\">-- Initialisation de `Current' utilisant `a_heure' comme `heure',<\/span>\r\n\t\t<span class=\"c1\">-- `a_minute' comme `minute' et `a_seconde' comme `seconde'<\/span>\r\n\t<span class=\"kr\">require<\/span>\r\n\t\t<span class=\"n\">Heure_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span>\r\n\t\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"n\">set_heure<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">set_minute<\/span><span class=\"p\">(<\/span><span class=\"n\">a_minute<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">set_seconde<\/span><span class=\"p\">(<\/span><span class=\"n\">a_seconde<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>Prendre note que pour cet exemple, je n&rsquo;ai pas mis les postconditions qui devraient normalement \u00eatre faites dans cette m\u00e9thode.<\/p>\n<p>On voit que cette m\u00e9thode n\u00e9cessite que le client de la classe envoie un argument <code>a_heure<\/code> inf\u00e9rieur \u00e0 24 ainsi que des arguments <code>a_minute<\/code> et <code>a_seconde<\/code> inf\u00e9rieur \u00e0 60 (puisque ce sont des <code>NATURAL<\/code>, les clients ne peuvent pas envoyer de sombre n\u00e9gatif en argument).<\/p>\n<p>En plus de v\u00e9rifier que les informations sont correctes lors du \u00ab\u00a0d\u00e9buguage\u00a0\u00bb du syst\u00e8me, les pr\u00e9conditions permettent aux clients de la classe de savoir ce qui devrait \u00eatre test\u00e9 afin d&rsquo;utiliser la m\u00e9thode. Par exemple, dans l&rsquo;exemple pr\u00e9c\u00e9dent, le client de la classe devrait s&rsquo;assurer que les pr\u00e9conditions sont respect\u00e9s en lan\u00e7ant la classe:<\/p>\n<div class=\"highlight\">\n<pre>\t\t<span class=\"kr\">if<\/span> <span class=\"n\">l_heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">l_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">l_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span> <span class=\"kr\">then<\/span>\r\n\t\t\t<span class=\"kr\">create<\/span> <span class=\"n\">l_temps<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span> <span class=\"p\">(<\/span><span class=\"n\">l_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">l_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">l_seconde<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"kr\">else<\/span>\r\n\t\t\t<span class=\"n\">print<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Une valeur n'est pas valide.%N\"<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h3>Note sur l&rsquo;h\u00e9ritage<\/h3>\n<p>Il est \u00e0 noter qu&rsquo;il est possible de mettre une pr\u00e9condition \u00e0 une m\u00e9thode qui est red\u00e9finie. Par contre, au lieu d&rsquo;utiliser la clause \u00ab\u00a0require\u00a0\u00bb, il faut utiliser la clause \u00ab\u00a0require else\u00a0\u00bb. Il est \u00e9galement \u00e0 noter que la m\u00e9thode pourra \u00eatre ex\u00e9cut\u00e9e \u00e0 l&rsquo;instant ou les pr\u00e9conditions d&rsquo;une des classes (enfants ou parents) sont valides. En d&rsquo;autres mots, c&rsquo;est un \u00ab\u00a0OU\u00a0\u00bb qui est fait entre les pr\u00e9conditions des diff\u00e9rentes classes de l&rsquo;h\u00e9ritage. Par exemple, supposons que je voulais faire une nouvelle classe qui ne limite pas l&rsquo;heure \u00e0 24 heures. Voici comment la classe pourrait \u00eatre \u00e9crite:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kr\">class<\/span>\r\n\t<span class=\"nc\">TEMPS_SANS_FIN<\/span>\r\n\r\n<span class=\"kr\">inherit<\/span>\r\n\t<span class=\"nc\">TEMPS<\/span>\r\n\t\t<span class=\"kr\">redefine<\/span>\r\n\t\t\t<span class=\"n\">make<\/span><span class=\"p\">,<\/span> <span class=\"n\">set_heure<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n<span class=\"kr\">create<\/span>\r\n\t<span class=\"n\">make<\/span>\r\n\r\n<span class=\"kr\">feature<\/span> <span class=\"p\">{<\/span><span class=\"kr\">NONE<\/span><span class=\"p\">}<\/span> <span class=\"c1\">-- Initialisation<\/span>\r\n\r\n\t<span class=\"n\">make<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- &lt;Precursor&gt;<\/span>\r\n\t\t<span class=\"kr\">require<\/span> <span class=\"kr\">else<\/span>\r\n\t\t\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"kc\">Precursor<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_seconde<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n<span class=\"kr\">feature<\/span> <span class=\"c1\">-- Access<\/span>\r\n\r\n\t<span class=\"n\">set_heure<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- &lt;Precursor&gt;<\/span>\r\n\t\t<span class=\"kr\">require<\/span> <span class=\"kr\">else<\/span>\r\n\t\t\t<span class=\"kc\">True<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"kc\">Precursor<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>Le \u00ab\u00a0require else True\u00a0\u00bb de la m\u00e9thode <code>set_heure<\/code> permet en fait d&rsquo;enlever compl\u00e8tement les pr\u00e9conditions de tous les parents.<\/p>\n<h2>Les postconditions<\/h2>\n<p>Les postconditions d&rsquo;une m\u00e9thode permettent de s&rsquo;assurer que la m\u00e9thode en question a effectu\u00e9 son travail correctement. Normalement, dans une m\u00e9thode correctement \u00e9crite, si les pr\u00e9conditions de la m\u00e9thode passent sans erreur, la m\u00e9thode devrait se terminer correctement et les postconditions devraient \u00eatre vraies, peu importe les arguments envoy\u00e9s et l&rsquo;\u00e9tat d&rsquo;origine de l&rsquo;objet. Les postconditions sont plac\u00e9es dans la clause \u00ab\u00a0ensure\u00a0\u00bb de la m\u00e9thode. Voici la m\u00e9thode pr\u00e9c\u00e9dente avec les postconditions:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">make<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"c1\">-- Initialisation de `Current' utilisant `a_heure' comme `heure',<\/span>\r\n\t\t<span class=\"c1\">-- `a_minute' comme `minute' et `a_seconde' comme `seconde'<\/span>\r\n\t<span class=\"kr\">require<\/span>\r\n\t\t<span class=\"n\">Heure_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span>\r\n\t\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"n\">set_heure<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">set_minute<\/span><span class=\"p\">(<\/span><span class=\"n\">a_minute<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"n\">set_seconde<\/span><span class=\"p\">(<\/span><span class=\"n\">a_seconde<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">ensure<\/span>\r\n\t\t<span class=\"n\">Heure_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_heure<\/span>\r\n\t\t<span class=\"n\">Minute_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_minute<\/span>\r\n\t\t<span class=\"n\">seconde_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_seconde<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>On voit ici que la m\u00e9thode garantit que les trois (3) attributs (heure, minute et seconde) seront correctement assign\u00e9s en fonction des valeurs des trois (3) arguments (a_heure, a_minute et a_seconde).<\/p>\n<p>Du c\u00f4t\u00e9 du client, il est int\u00e9ressant de comprendre que la postcondition d&rsquo;une m\u00e9thode peut servir de validation pour les pr\u00e9conditions d&rsquo;une autre m\u00e9thode. Par exemple, dans l&rsquo;exemple de la classe <code>TEMPS<\/code> vu plus haut, puisque les postconditions garantissent que les attributs (heure, minute et seconde) sont corrects, il n&rsquo;est pas n\u00e9cessaire de valider les valeurs (avec un <code>if<\/code> comme dans l&rsquo;exemple dans la section sur les pr\u00e9conditions). Par exemple, on peut simplement faire le code suivant:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">l_temps1<\/span><span class=\"p\">.<\/span><span class=\"n\">set_heure<\/span> <span class=\"p\">(<\/span><span class=\"n\">l_temps2<\/span><span class=\"p\">.<\/span><span class=\"n\">heure<\/span><span class=\"p\">)<\/span>\r\n<\/pre>\n<\/div>\n<p>en \u00e9tant persuad\u00e9 que la pr\u00e9condition de <code>set_heure<\/code> (que l&rsquo;heure est inf\u00e9rieur \u00e0 24) est valide. Lorsque les pr\u00e9conditions et les postconditions sont bien fait, cet effet \u00ab\u00a0domino\u00a0\u00bb (les postconditions valide les pr\u00e9conditions) arrivent beaucoup.<\/p>\n<p>On peut utiliser le mot cl\u00e9 <code>old<\/code> pour aller chercher la valeur telle qu&rsquo;elle \u00e9tait avant l&rsquo;utilisation de la m\u00e9thode. Par exemple:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">ajouter<\/span><span class=\"p\">(<\/span><span class=\"n\">a_element<\/span><span class=\"p\">:<\/span><span class=\"kr\">like<\/span> <span class=\"n\">element<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">deferred<\/span>\r\n\t<span class=\"kr\">ensure<\/span>\r\n\t\t<span class=\"n\">Element_Ajoute<\/span><span class=\"p\">:<\/span> <span class=\"n\">nombre_elements<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">nombre_elements<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h3>Note sur l\u2019h\u00e9ritage<\/h3>\n<p>Il est \u00e0 noter qu&rsquo;il est possible de mettre une postcondition \u00e0 une m\u00e9thode qui est red\u00e9finie. Par contre, au lieu d&rsquo;utiliser la clause \u00ab\u00a0ensure\u00a0\u00bb, il faut utiliser la clause \u00ab\u00a0ensure then\u00a0\u00bb. Il est \u00e9galement \u00e0 noter que la m\u00e9thode devra respecter l&rsquo;enti\u00e8ret\u00e9 des postcondition des classes de l&rsquo;arbre d&rsquo;h\u00e9ritage (enfants ou parents). En d&rsquo;autres mots, c&rsquo;est un \u00ab\u00a0ET\u00a0\u00bb qui est fait entre les postconditions des diff\u00e9rentes classes de l&rsquo;h\u00e9ritage. Par exemple:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">ajouter<\/span><span class=\"p\">(<\/span><span class=\"n\">a_element<\/span><span class=\"p\">:<\/span><span class=\"kr\">like<\/span> <span class=\"n\">element<\/span><span class=\"p\">)<\/span>\r\n\t<span class=\"kr\">deferred<\/span>\r\n\t<span class=\"kr\">ensure<\/span> <span class=\"kr\">then<\/span>\r\n\t\t<span class=\"n\">Element_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">dernier_element<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_element<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h2>Invariants de classe<\/h2>\n<p>Les invariants de classes permettent d&rsquo;indiquer ce qui doit toujours \u00eatre vrai dans la classe en cours. Les invariants de classes se trouvent toujours \u00e0 la fin de la classe, dans la clause \u00ab\u00a0invariant\u00a0\u00bb, avant le \u00ab\u00a0end\u00a0\u00bb final de la classe.<\/p>\n<p>Voici la classe de <code>TEMPS<\/code> complet avec les invariants \u00e0 la fin:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kr\">note<\/span>\r\n\t<span class=\"n\">description<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Repr\u00e9sente un temps (heure, minute et seconde) d'une journ\u00e9e\"<\/span>\r\n\t<span class=\"n\">author<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Louis Marchand\"<\/span>\r\n\t<span class=\"n\">date<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Fri, 27 Nov 2020 19:22:47 +0000\"<\/span>\r\n\t<span class=\"n\">revision<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"0.1\"<\/span>\r\n\r\n<span class=\"kr\">class<\/span>\r\n\t<span class=\"nc\">TEMPS<\/span>\r\n\r\n<span class=\"kr\">create<\/span>\r\n\t<span class=\"n\">make<\/span>\r\n\r\n<span class=\"kr\">feature<\/span> <span class=\"p\">{<\/span><span class=\"kr\">NONE<\/span><span class=\"p\">}<\/span> <span class=\"c1\">-- Initialisation<\/span>\r\n\r\n\t<span class=\"n\">make<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_minute<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- Initialisation de `Current' utilisant `a_heure' comme `heure',<\/span>\r\n\t\t\t<span class=\"c1\">-- `a_minute' comme `minute' et `a_seconde' comme `seconde'.<\/span>\r\n\t\t<span class=\"kr\">require<\/span>\r\n\t\t\t<span class=\"n\">Heure_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span>\r\n\t\t\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"n\">set_heure<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">set_minute<\/span><span class=\"p\">(<\/span><span class=\"n\">a_minute<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"n\">set_seconde<\/span><span class=\"p\">(<\/span><span class=\"n\">a_seconde<\/span><span class=\"p\">)<\/span>\r\n\t\t<span class=\"kr\">ensure<\/span>\r\n\t\t\t<span class=\"n\">Heure_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_heure<\/span>\r\n\t\t\t<span class=\"n\">Minute_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_minute<\/span>\r\n\t\t\t<span class=\"n\">seconde_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_seconde<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n<span class=\"kr\">feature<\/span> <span class=\"c1\">-- Acc\u00e8s<\/span>\r\n\r\n\t<span class=\"n\">heure<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span>\r\n\t\t\t<span class=\"c1\">-- Le nombre d'heures s'\u00e9tant d\u00e9roul\u00e9s depuis minuit.<\/span>\r\n\r\n\t<span class=\"n\">set_heure<\/span><span class=\"p\">(<\/span><span class=\"n\">a_heure<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- Assigne `heure' avec la valeur de `a_heure'.<\/span>\r\n\t\t<span class=\"kr\">require<\/span>\r\n\t\t\t<span class=\"n\">Heure_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"n\">heure<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_heure<\/span>\r\n\t\t<span class=\"kr\">ensure<\/span>\r\n\t\t\t<span class=\"n\">Heure_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_heure<\/span>\r\n\t\t\t<span class=\"n\">Minute_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">minute<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">seconde<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n\t<span class=\"n\">minute<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span>\r\n\t\t\t<span class=\"c1\">-- Le nombre de minutes s'\u00e9tant d\u00e9roul\u00e9s depuis le d\u00e9but de l'heure.<\/span>\r\n\r\n\t<span class=\"n\">set_minute<\/span><span class=\"p\">(<\/span><span class=\"n\">a_minute<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- Assigne `minute' avec la valeur de `a_minute'.<\/span>\r\n\t\t<span class=\"kr\">require<\/span>\r\n\t\t\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"n\">minute<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_minute<\/span>\r\n\t\t<span class=\"kr\">ensure<\/span>\r\n\t\t\t<span class=\"n\">Heure_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">heure<\/span>\r\n\t\t\t<span class=\"n\">Minute_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_minute<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">seconde<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n\t<span class=\"n\">seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span>\r\n\t\t\t<span class=\"c1\">-- Le nombre de secondes s'\u00e9tant d\u00e9roul\u00e9s depuis le d\u00e9but de la minute.<\/span>\r\n\r\n\t<span class=\"n\">set_seconde<\/span><span class=\"p\">(<\/span><span class=\"n\">a_seconde<\/span><span class=\"p\">:<\/span><span class=\"nc\">NATURAL_8<\/span><span class=\"p\">)<\/span>\r\n\t\t\t<span class=\"c1\">-- Assigne `seconde' avec la valeur de `a_seconde'.<\/span>\r\n\t\t<span class=\"kr\">require<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"n\">seconde<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_seconde<\/span>\r\n\t\t<span class=\"kr\">ensure<\/span>\r\n\t\t\t<span class=\"n\">Heure_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">heure<\/span>\r\n\t\t\t<span class=\"n\">Minute_Inchange<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">=<\/span> <span class=\"kr\">old<\/span> <span class=\"n\">minute<\/span>\r\n\t\t\t<span class=\"n\">Seconde_Assigne<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">=<\/span> <span class=\"n\">a_seconde<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\r\n<span class=\"kr\">invariant<\/span>\r\n\t<span class=\"n\">Heure_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">heure<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">24<\/span>\r\n\t<span class=\"n\">Minute_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">minute<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t<span class=\"n\">Seconde_Valide<\/span><span class=\"p\">:<\/span> <span class=\"n\">seconde<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">60<\/span>\r\n\t\r\n<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h2>Comment bien lire les contrats<\/h2>\n<p>Pour \u00e9crire de bons contrats efficaces, il est important de bien comprendre comment lire correctement ces contrats.<\/p>\n<p>La meilleure fa\u00e7on de comprendre les contrats dans un contexte de programmation orient\u00e9e objet est de se le repr\u00e9senter comme \u00e9tant une transaction entre un client et un fournisseur.<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Le client a certaines obligations envers le fournisseur.\n<ul>\n<li>Par exemple, le client doit payer pour les services offerts par le fournisseur.<\/li>\n<li>En programmation, les obligations du client sont inscrites dans les pr\u00e9conditions.<\/li>\n<\/ul>\n<\/li>\n<li>Le fournisseur a \u00e9galement certaines obligations.\n<ul>\n<li>Par exemple, le fournisseur doit offrir les services requis.<\/li>\n<li>En programmation, les obligations du fournisseur sont inscrites dans les postconditions.<\/li>\n<\/ul>\n<\/li>\n<li>Dans tous les cas, autant le client que le fournisseur doivent respecter les lois en vigueur.\n<ul>\n<li>En programmation, les lois sont les invariants de classe.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Les autres types de contrats<\/h2>\n<p>Eiffel permet d&rsquo;autres types de contrats qui ne seront pas \u00e9valu\u00e9s dans ce cours. Je vais faire ici un petit survol de ces contrats.<\/p>\n<h3>Les assertions simples<\/h3>\n<p>Les assertions simples permettent de valider un \u00e9l\u00e9ment du code, en temps r\u00e9el. C&rsquo;est exactement la m\u00eame chose que les assertions que nous pouvons trouver dans la majorit\u00e9 des langages. L&rsquo;assertion simple se place dans une clause \u00ab\u00a0check\u00a0\u00bb. Par exemple:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">l_valeur<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">get_valeur<\/span>\r\n<span class=\"kr\">check<\/span> <span class=\"n\">Valeur_Non_Null<\/span><span class=\"p\">:<\/span> <span class=\"n\">l_valeur<\/span> <span class=\"o\">\/=<\/span> <span class=\"mi\">0<\/span> <span class=\"kr\">end<\/span>\r\n<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">10<\/span> <span class=\"o\">\/<\/span> <span class=\"n\">l_valeur<\/span>\r\n<\/pre>\n<\/div>\n<p>Il est \u00e0 noter qu&rsquo;on peut utiliser l&rsquo;assertion simple sous la forme d&rsquo;un \u00ab\u00a0if\u00a0\u00bb. Par exemple:<\/p>\n<div class=\"highlight\">\n<pre><span><\/span><span class=\"n\">l_valeur<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">get_valeur<\/span>\r\n<span class=\"kr\">check<\/span> <span class=\"n\">Valeur_Non_Null<\/span><span class=\"p\">:<\/span> <span class=\"n\">l_valeur<\/span> <span class=\"o\">\/=<\/span> <span class=\"mi\">0<\/span> <span class=\"kr\">then<\/span>\r\n\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">10<\/span> <span class=\"o\">\/<\/span> <span class=\"n\">l_valeur<\/span>\r\n<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h3>Les variants de boucle<\/h3>\n<p>Un variant de boucle est un contrat qui permet de s&rsquo;assurer qu&rsquo;une boucle se terminera correctement. En fait, \u00e7a permet de s&rsquo;assurer qu&rsquo;une boucle n&rsquo;est pas sans fin. Un variant de boucle est une instruction qui retourne un entier. Cet entier doit toujours diminuer, sans jamais atteindre la valeur 0. On place cette instruction dans une clause \u00ab\u00a0variant\u00a0\u00bb, apr\u00e8s le corps de la boucle.<\/p>\n<p>Pour donner les exemples de variant et d&rsquo;invariant de boucle, j&rsquo;utiliserai la boucle suivante:<\/p>\n<div class=\"highlight\">\n<pre>\t<span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"n\">a_dividende<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_diviseur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span><span class=\"p\">):<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t\t\t<span class=\"c1\">-- Effectue une division enti\u00e8re entre `a_dividende' et `a_diviseur'<\/span>\r\n\t\t<span class=\"kr\">local<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t\t<span class=\"kr\">do<\/span>\r\n\t\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">0<\/span>\r\n\t\t\t<span class=\"kr\">from<\/span>\r\n\t\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_dividende<\/span>\r\n\t\t\t<span class=\"kr\">until<\/span>\r\n\t\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t\t<span class=\"kr\">loop<\/span>\r\n\t\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_reste<\/span> <span class=\"o\">-<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">Result<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\r\n\t\t\t<span class=\"kr\">end<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<p>Si j&rsquo;ex\u00e9cute cette m\u00e9thode comme ceci:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">print<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Le resultat: \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">).<\/span><span class=\"n\">out<\/span> <span class=\"o\">+<\/span> <span class=\"s\">\"%N\"<\/span><span class=\"p\">)<\/span>\r\n<\/pre>\n<\/div>\n<p>\u00c7a donne la r\u00e9ponse pr\u00e9vue (c&rsquo;est-\u00e0-dire: 3). Mais si j&rsquo;utilise ceci:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">print<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Le resultat: \"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">).<\/span><span class=\"n\">out<\/span> <span class=\"o\">+<\/span> <span class=\"s\">\"%N\"<\/span><span class=\"p\">)<\/span>\r\n<\/pre>\n<\/div>\n<p>J&rsquo;obtiens une boucle sans fin. Si j&rsquo;avais fait un variant de boucle comme ceci:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"n\">a_dividende<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_diviseur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span><span class=\"p\">):<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t\t<span class=\"c1\">-- Effectue une division enti\u00e8re entre `a_dividende' et `a_diviseur'<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_reste<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">0<\/span>\r\n\t\t<span class=\"kr\">from<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_dividende<\/span>\r\n\t\t<span class=\"kr\">until<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t<span class=\"kr\">loop<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_reste<\/span> <span class=\"o\">-<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">Result<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\r\n\t\t<span class=\"kr\">variant<\/span>\r\n\t\t\t<span class=\"n\">Reste_Diminue<\/span><span class=\"p\">:<\/span> <span class=\"n\">l_reste<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">end&lt;\/s\r\n<\/span><\/pre>\n<\/div>\n<p>Le d\u00e9boguer m&rsquo;informerait d\u00e8s la fin de la premi\u00e8re utilisation du corps de la boucle puisque la variable <code>l_reste<\/code> n&rsquo;a pas \u00e9t\u00e9 modifi\u00e9e par rapport au d\u00e9but de la boucle.<\/p>\n<p>Le variant de boucle, dans ce cas, nous montre qu&rsquo;il manque une pr\u00e9conditon \u00e0 la fonction. Voici la m\u00e9thode avec la pr\u00e9condition.<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"n\">a_dividende<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_diviseur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span><span class=\"p\">):<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t\t<span class=\"c1\">-- Effectue une division enti\u00e8re entre `a_dividende' et `a_diviseur'<\/span>\r\n\t<span class=\"kr\">require<\/span>\r\n\t\t<span class=\"n\">Diviseur_Non_Null<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_diviseur<\/span> <span class=\"o\">\/=<\/span> <span class=\"mi\">0<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_reste<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">0<\/span>\r\n\t\t<span class=\"kr\">from<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_dividende<\/span>\r\n\t\t<span class=\"kr\">until<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t<span class=\"kr\">loop<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_reste<\/span> <span class=\"o\">-<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">Result<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\r\n\t\t<span class=\"kr\">variant<\/span>\r\n\t\t\t<span class=\"n\">Reste_Diminue<\/span><span class=\"p\">:<\/span> <span class=\"n\">l_reste<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h3>Invariant de boucle<\/h3>\n<p>Un invariant de boucle permet de s&rsquo;assurer que les valeurs g\u00e9n\u00e9r\u00e9es dans la boucle sont toujours valides. Ce type de contrat est g\u00e9n\u00e9ralement tr\u00e8s difficile \u00e0 faire et n\u00e9cessite g\u00e9n\u00e9ralement des notions math\u00e9matiques assez avanc\u00e9es. L&rsquo;invariant de boucle est une instruction qui retourne une valeur bool\u00e9enne et qui doit toujours retourner vraie, avant l&rsquo;ex\u00e9cution de toutes les it\u00e9rations de la boucle. On place l&rsquo;invariant de boucle dans la clause \u00ab\u00a0invariant\u00a0\u00bb avant la condition de la boucle (avant le \u00ab\u00a0until\u00a0\u00bb). Voici un exemple en utilisant la division enti\u00e8re vue plus haut:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"n\">division_entiere<\/span><span class=\"p\">(<\/span><span class=\"n\">a_dividende<\/span><span class=\"p\">,<\/span> <span class=\"n\">a_diviseur<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span><span class=\"p\">):<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t\t<span class=\"c1\">-- Effectue une division enti\u00e8re entre `a_dividende' et `a_diviseur'<\/span>\r\n\t<span class=\"kr\">require<\/span>\r\n\t\t<span class=\"n\">Diviseur_Non_Null<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_diviseur<\/span> <span class=\"o\">\/=<\/span> <span class=\"mi\">0<\/span>\r\n\t<span class=\"kr\">local<\/span>\r\n\t\t<span class=\"n\">l_reste<\/span><span class=\"p\">:<\/span><span class=\"nc\">INTEGER<\/span>\r\n\t<span class=\"kr\">do<\/span>\r\n\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"mi\">0<\/span>\r\n\t\t<span class=\"kr\">from<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">a_dividende<\/span>\r\n\t\t<span class=\"kr\">invariant<\/span>\r\n\t\t\t<span class=\"n\">Reversible<\/span><span class=\"p\">:<\/span> <span class=\"n\">a_dividende<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">Result<\/span> <span class=\"o\">*<\/span> <span class=\"n\">a_diviseur<\/span> <span class=\"o\">+<\/span> <span class=\"n\">l_reste<\/span>\r\n\t\t<span class=\"kr\">until<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t<span class=\"kr\">loop<\/span>\r\n\t\t\t<span class=\"n\">l_reste<\/span> <span class=\"o\">:=<\/span> <span class=\"n\">l_reste<\/span> <span class=\"o\">-<\/span> <span class=\"n\">a_diviseur<\/span>\r\n\t\t\t<span class=\"kc\">Result<\/span> <span class=\"o\">:=<\/span> <span class=\"kc\">Result<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\r\n\t\t<span class=\"kr\">variant<\/span>\r\n\t\t\t<span class=\"n\">Reste_Diminue<\/span><span class=\"p\">:<\/span> <span class=\"n\">l_reste<\/span>\r\n\t\t<span class=\"kr\">end<\/span>\r\n\t<span class=\"kr\">end<\/span>\r\n<\/pre>\n<\/div>\n<h2>Les contrats dans les autres langages<\/h2>\n<p>Eiffel est le premier langage \u00e0 avoir impl\u00e9ment\u00e9 les contrats dans le langage. Il est \u00e0 noter que depuis, plusieurs langages comme C#, Ada, Closure, Kotlin ou Scala ont int\u00e9gr\u00e9 directement les contrats dans leurs langages. Par contre, d&rsquo;autres langages peuvent utiliser des librairies logicielles externes afin d&rsquo;ajouter au langage un syst\u00e8me de contrat. Parmi eux, nous pouvons nommer Java, JavaScript, C, C++, Go, Python, PHP, etc.<\/p>\n<p>La grosse probl\u00e9matique dans ces derniers langages, c&rsquo;est que souvent, les librairies de base ne sont pas adapt\u00e9es \u00e0 l&rsquo;utilisation de contrat. En effet, pour pouvoir utiliser au maximum les contrats, il faut s&rsquo;assurer que les fonctions que nous utilisons sont pures. Par contre, certaines m\u00e9thodes dans les librairies de bases de ces langages ne sont pas pures. Par exemple: en Java, il est impossible de faire un contrat en utilisant le prochain \u00e9l\u00e9ment dans un <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/Iterator.html\">Iterator<\/a>.<\/p>\n<p><a href=\"https:\/\/www.louismarchand.me\/index.php\/les-cours\/programmation-orientee-objet-2\/\">Retour<\/a><\/p>\n<hr \/>\n<p>Auteur: Louis Marchand<br \/>\n<a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/i.creativecommons.org\/l\/by\/4.0\/80x15.png\" alt=\"Creative Commons License\" \/><\/a><br \/>\nSauf pour les sections sp\u00e9cifi\u00e9es autrement, ce travail est sous licence <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\">Creative Commons Attribution 4.0 International<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction En programmation orient\u00e9e par objets, le secret permettant de cr\u00e9er des classes robustes et le plus possible r\u00e9utilisables possible est de s&rsquo;assurer de garder une grande rigueur dans la programmation de ces classes. Cette rigueur passe par plusieurs \u00e9l\u00e9ments comme s&rsquo;assurer de bien comprendre le code de nos classes, bien documenter ces derni\u00e8res et&hellip; <a class=\"more-link\" href=\"https:\/\/www.louismarchand.me\/index.php\/objet2-le-design-par-contrats\/\">Continue reading <span class=\"screen-reader-text\">Le \u00ab\u00a0design\u00a0\u00bb par contrats<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-485","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/comments?post=485"}],"version-history":[{"count":2,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/485\/revisions"}],"predecessor-version":[{"id":488,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/485\/revisions\/488"}],"wp:attachment":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/media?parent=485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}