locked
[WF4] Optimiser l’implémentation des activités composites RRS feed

  • Discussion générale

  • Ecrire une activité composite tout en code n’a rien de très joyeux et une activité composite écrite en mode impératif (C# ou Vb) peut vite devenir moins performante que la même activité écrite de manière déclarative (Xaml). On peut même se retrouver avec des comportements inattendues :

    • Définition de l’activité qui n’est pas mise à jours alors que le code de l’activité a été modifié :(
    • Consommation anormale de  ressources mémoire :(

    Pour éviter cela, il suffit de ne pas céder aux tendance du moment :

    • Affectation de l’implémentation dans le constructeur de l’activité sans toucher à la propriété Implementation.
    • Ecriture d’un code d’implémentation imbuvable et impossible à distinguer du reste de l’activité.
    • Ecriture de la méthode Get() de la propriété Implementation sans se soucier du Set().

    Ces erreurs coutent chère, très chère. Pour les éviter ceci il suffit d’utiliser un Template de code similaire à celui-ci :

    01.public class CompositeActivity : Activity
    02.{
    03.    // Délégué de l'implémentation
    04.    private Func<Activity> m_Implementation;
    05.  
    06.    /// <summary>
    07.    /// Implémentation
    08.    /// </summary>
    09.    protected override Func<Activity> Implementation
    10.    {
    11.        get
    12.        {
    13.            if (this.m_Implementation == null)
    14.            {
    15.                this.m_Implementation = this.GetImplementation;
    16.            }
    17.            return this.m_Implementation;
    18.        }
    19.        set
    20.        {
    21.            // Surtout ne rien coder ici, l’implémentation reste interne!
    22.        }
    23.    }
    24.  
    25.    /// <summary>
    26.    /// Code impératif de l'implémentation
    27.    /// </summary>
    28.    /// <returns></returns>
    29.    private Activity GetImplementation()
    30.    {
    31.        return new Sequence
    32.            {
    33.                Activities =
    34.                {
    35.                    new WriteLine { Text = "Hello" },
    36.                    new WriteLine { Text = "World!" }
    37.                }
    38.            };
    39.    }
    40.}

    Décortiquons ce code :

    1. La propriété Implementation est réécrite afin de rendre indisponible la méthode Set(). Logique, la définition de notre activité reste de la responsabilité de notre activité, pas du workflow qui va l’utiliser!
    2. Une variable interne m_Implementation a été déclarer afin d’optimiser les appels à la méthode GetImplementation() afin de ne pas instancier un délégué à chaque appel.
    3. La méthode GetImplemenation() ne se charge que de fournir l’implémentation de l’activité. Comme cela, pas de risque de s’emmêler les pinceaux quand l’activité serra devenue plus conséquente.

    Mais pour les acharnés de l’optimisation ou de la qualité de code il est évidant qu’un petit readonly serrait le bienvenu et une petite méthode statique vue que l’on n’utilise pas d’arguments ;)

    01.public class CompositeActivity : Activity
    02.{
    03.    // Délégué de l'implémentation
    04.    private readonly Func<Activity> m_Implementation;
    05.  
    06.    public CompositeActivity()
    07.    {
    08.        this.m_Implementation = new Func<Activity>(GetImplementation);
    09.    }
    10.  
    11.    /// <summary>
    12.    /// Implémentation
    13.    /// </summary>
    14.    protected override Func<Activity> Implementation
    15.    {
    16.        get
    17.        {
    18.            return this.m_Implementation;
    19.        }
    20.        set
    21.        {
    22.            // ...
    23.        }
    24.    }
    25.  
    26.    /// <summary>
    27.    /// Code impératide de l'implémentation
    28.    /// </summary>
    29.    /// <returns></returns>
    30.    private static Activity GetImplementation()
    31.    {
    32.        return new Sequence
    33.            {
    34.                Activities =
    35.                {
    36.                    new WriteLine { Text = "Welcome" },
    37.                    new WriteLine { Text = "in my" },
    38.                    new WriteLine { Text = "World!" }
    39.                }
    40.            };
    41.    }
    42.}

    Bien entendu, si votre activité a besoin d’arguments, il faudra modifier la méthode statique.

    Par exemple :

    01.public class CompositeActivity : Activity
    02.{
    03.    // Délégué de l'implémentation
    04.    private readonly Func<Activity> m_Implementation;
    05.    public InArgument<String> Text { get; set; }
    06.  
    07.    public CompositeActivity()
    08.    {
    09.        this.m_Implementation = new Func<Activity>(GetImplementation);
    10.    }
    11.  
    12.    /// <summary>
    13.    /// Implémentation
    14.    /// </summary>
    15.    protected override Func<Activity> Implementation
    16.    {
    17.        get
    18.        {
    19.            return this.m_Implementation;
    20.        }
    21.        set
    22.        {
    23.            // ...
    24.        }
    25.    }
    26.  
    27.    /// <summary>
    28.    /// Code impératide de l'implémentation
    29.    /// </summary>
    30.    /// <returns></returns>
    31.    private  Activity GetImplementation()
    32.    {
    33.        return new Sequence
    34.            {
    35.                Activities =
    36.                {
    37.                    new WriteLine { Text = new InArgument<String>(c=> String.Format("Welcome {0}", this.Text.Get(c))) },
    38.                    new WriteLine { Text = "in my" },
    39.                    new WriteLine { Text = "World!" }
    40.                }
    41.            };
    42.    }
    43.}

    Et voila, j’espère avoir été claire ;)

     

    Lien vers l'article original :

    http://blogs.codes-sources.com/jeremyjeanson/archive/2010/07/19/wf4-optimiser-l-impl-mentation-de-vos-activit-s-composites.aspx

     


    Jérémy Jeanson MCP, MCTS http://blogs.codes-sources.com/JeremyJeanson/ (French or English spoken)
    lundi 26 juillet 2010 07:14
    Modérateur