Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe


Poster un commentaire

Patterns pour haute dispo et scalabilité d’une appli web – Partie II

Exploiter l’asynchronisme

Un thread est occupé lorsqu’il exécute du code. Cela ne signifie pas qu’il soit réellement utilisé. Il peut être en attente pour une des raisons suivantes:
  1. Le code effectue des manipulations de données en mémoire, il est en attente qu’une CPU devienne disponible.
    On parle de code lié à la CPU (CPU-bound)
  2. Le code est en attente d’une requête vers un composant situé en dehors de son process, il est alors I/O bound.
Ces situations ne sont pas très favorables car si le thread ne travaille pas, il n’est pas pour autant disponible pour d’autres tâches.
Une meilleure situation serait de le recycler en attendant que la cause du blocage se résolve.
Les techniques d’asynchronismes permettent d’organiser ce recyclage. Toutefois, l’asynchronisme a un coût. De plus, dans la mesure où le nombre de CPU est tout de même très limité sur un serveur, la mise en oeuvre de code asynchrone est surtout pertinente pour du code I/O bound.

Lire la suite


4 Commentaires

Ecrire du code SOLID

Il est fréquent et il est normal de faire évoluer du code.

Vous avez certainement constaté que certains se prêtent mieux que d’autres à l’exercice. Ils sont plus malléables, plus souples, plus agiles. Alors pourquoi existe t’il du code qui ressemble à ceci lorsque l’on tente de le modifier:

2016-01-30_12-59-16

et d’autre plutôt à:

2016-01-30_13-02-06

 

Plusieurs années de recherche on conduit à dégager un petit nombre de caractéristiques qui assurent que du code restera flexible. Ces principes ont été compilés au début des années 2000 par Robert C. Martin sous l’acronyme de code SOLID. L’acronyme fut proposé par Michael Feather.

 

Je vais consacrer cet article à décortiquer ce qu’est du code SOLID. Comment on le met en œuvre, comment on le reconnaît. Puisque SOLID est en quelque sorte la grammaire qui sert à construire les patterns, je profiterai de cet article pour mettre en avant les patterns les plus courants, en tout cas le minimum que vous devez connaître.

SOLID est en effet la porte d’entrée pour comprendre le rôle des patterns, d’où sortent t’ils? Un pattern qui n’est pas SOLID n’est probablement pas un pattern.

 

Si vous souhaitez aller plus loin, je vous recommande chaudement l’acquisition de ce livre.

2016-01-30_13-07-10

C’est un livre agréable à lire, Martin est un développeur, mais très dense. Prévoyez plusieurs lectures.

Lire la suite


Poster un commentaire

Inversion de contrôle, Injection de dépendance et Service locator

A l’origine de ces techniques, la volonté de maîtriser la complexité des applications et des frameworks.

Comment s’assurer que le code soit testable unitairement?

Comment maîtriser les impacts d’un correctif ou d’une évolution?

Comment organiser du code en unités logiques plus faciles à comprendre?

Comment ajouter de nouvelles fonctionnalités?

Peut t’on choisir dynamiquement un comportement?

 

Supposons par exemple que nous disposions d’une Dll MyDll, on pourrait écrire typiquement ce type de code:

using MyDll;

class ClasseX
{
   void MaFonction()
   {
       ClasseY maClasseY = new ClasseY();
       maClasseY.LireDonnees();
       maClasseY.TraitementDonnees();
   }
}

C’est la structure du code qui nous intéresse, on pourrait la représenter ainsi: 2015-09-04_09-27-04 On a une classe ClasseX qui constitue notre application. Cette classe utilise ClasseY venue de la Dll. Il existe donc une dépendance de ClasseX envers ClasseY.

Si vous réexaminez la liste (non exhaustive) de questions posées en début de ce texte, il n’est pas difficile de voir les nuages qui se profilent à l’horizon. Par exemple il n’est pas facile de remplacer ClasseY par ClasseZ qui implémente un autre algorithme de traitement des données, surtout si ClasseY est utilisée un peu partout dans l’application. Et ce n’est qu’un exemple, de multiples autres Dll peuvent parfaitement être utilisées tout au long de l’application. La difficulté croît de façon exponentielle.

L’application sera difficilement maintenable.

Lire la suite


Poster un commentaire

Le pattern PRG

Supposons que l’on écrive le code suivant:


@model WebApplication12.Models.Location
<form method="post">
    @Html.LabelFor(m=>m.Pays)
    @Html.TextBoxFor(m=>m.Pays,new {placeholder="Entrer un pays"})
    <br/>
    @Html.LabelFor(m => m.Ville)
    @Html.TextBoxFor(m => m.Ville, new { placeholder = "Entrer une ville" })

    <br/>
    <button type="submit">Sauver</button>
</form>

Côté contrôleur:


public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(Location location)
    {
        return View();
    }
}

Vous reconstituerez facilement le modèle.

  •  Lancez l’application
  • Faites une saisie
  • Soumettez le formulaire
  • Faites F5 pour le reposter

Un formulaire similaire à celui-ci devrait s’afficher:

2014-07-07_09-36-37

Outre que ce message est incompréhensible pour un utilisateur lambda il pose plusieurs problèmes:

  • On s’attend à rafraîchir la page, en réalité on répète l’action du POST ce qui n’est pas tout à fait la même chose. Des effets indésirables peuvent en résulter
  • Une réponse POST ne peut pas facilement être mise dans les favoris. C’est aussi potentiellement une source de problèmes.
  • Si vous faites un back dans le navigateur, au lieu de réafficher la page, vous allez en plus réitérer l’action du POST.
    Là aussi des effets indésirables peuvent en résulter

 

C’est pour essayer de contrôler ce problème que certains développeurs utilisent le modèle PRG (POST/Redirect/GET).

Note: l’expression employée dans la littérature est PRG pattern.
Je ne suis pas convaincu de voir là un pattern justement. D’abord parce qu’il est loin de résoudre entièrement le problème et de plus il présente des effets de bords pas forcément souhaitables. Il me semble préférable de dire qu’il s’agit d’un choix d’implémentation à discuter avec votre architecte ou votre lead technique.

Lire la suite


Poster un commentaire

Comparaison des patrons Proxy, Adaptateur et façade

Le patron Proxy (Proxy Pattern) est très important et très courant. Il est notamment le chef d’orchestre des architectures distribuées qui deviennent peu à peu la norme sous l’influence de la mobilité en particulier. Il est donc important de le comprendre.

Un proxy est une classe utilisée à la place d’une autre classe appelée classe réelle. Le cas le plus fréquent est toutefois celui où la classe réelle est un service. Le proxy est la classe client qui agira à la place de celle-ci. Mais d’une façon générale toute abstraction implémente un patron proxy. Par exemple la classe FileStream est un proxy pour un fichier.

Graphiquement ce pattern est représenté ainsi:

2014-07-02_21-13-21

Une classe client consomme une instance d’une interface IProxy décrivant l’interface d’une classe réelle appelée ClasseReelle. En réalité le client ne va pas recevoir l’instance de ClasseReelle, mais une instance d’une autre classe Proxy qui implémente également IProxy. Proxy agit donc à la place de ClasseReelle.

En interne Proxy va peut être instancier ClasseReelle ou bien se connecter à ClasseReelle via un service web ou tout ce que l’on peut imaginer.

Jusque là tout paraît clair, tout au plus peut t’on se demander pourquoi ClasseReelle devrait implémenter IProxy.

Lire la suite