SOLID

SOLID, un acronyme qui représente les 5 principes de base pour la programmation orientée objet. SOLID permet le développement de logiciel plus fiable et plus robuste.

S: Single Responsability Principle
Une classe doit avoir une seule responsabilité. Cela réduit le risque d’effectuer des autres comportements sans relation.

O: Open/Closed Principle
Une classe doit être ouverte à l’extension, mais fermée à la modification. C’est-à-dire, ça doit être possible de faire une extension d’un comportement en créant une nouvelle classe – mais sans changement d’un codage existent.

L: Liskov Substitution Principle
Une instance de type T doit pouvoir être remplacée par une instance de type G, tel que G sous-type de T, sans que cela ne modifie la cohérence du programme

I: Interface Segragation Principle
Préférer plusieurs interfaces spécifiques pour chaque client plutôt qu’une seule interface générale.

D: Dependency Inversion Principle
Il faut dépendre des abstractions, pas des implémentations.
C’est-à-dire, SOLID aide le programmeur à créer des meilleurs logiciels. L’expression a été crée par Michael Feathers and Bob Martin.

Observer patron de conception (observer pattern)

Le patron de conception observer fait partie des patrons du groupe << Behavioral >> de GoF, qui s’occupe de la communication parmi les objets différents, on dirait. Il y a beaucoup de façons différents d’implémention d’un observer pattern. Le plus connu est probablement la gestion d’événements (Event Handling).

Le nom décrit plus ou moins la fonctionnalité : Observer. Donc un observer c’est quelque chose que regarde des autres objets. Donc l’observer est basée sur le Hollywood Principle : << Don’t call us, we call you >>.

Dans le codage suivant on jette un coup d’œil sur un exemple facile en C# :

namespace ObserverPattern
{
    #region interfaces

    interface ISubject
    {
        void Subscribe(Observer o);
        void Unsubscribe(Observer o);
        void Notify();
    }

    interface IObserver
    {
        void Update(string a);
    }

    #endregion

    #region classes

    /// <summary>
    /// Observer: maintient une référence au Subject et le statut actuel
    /// </summary>
    /// <seealso cref="ObserverPattern.IObserver" />
    class Observer : IObserver
    {
        public void Update(string animal)
        {
            Console.WriteLine("Nouveau au zoo");
            Console.WriteLine(animal);
            Console.WriteLine();
        }
    }

    /// <summary>
    /// Subject: maintient une liste d'Observers
    /// </summary>
    /// <seealso cref="ObserverPattern.ISubject" />
    class Subject : ISubject
    {
        private List<Observer> observers = new List<Observer>();
        private List<String> zoo = new List<String>(); 

        public void Subscribe(Observer o)
        {
            observers.Add(o);
        }

        public void Unsubscribe(Observer o)
        {
            observers.Remove(o);
        }

        public void Notify()
        {
            foreach (var o in observers)
            {
                o.Update(zoo[zoo.Count - 1]);
            }
        }

        public void ReleaseAnimal(string animal)
        {
            zoo.Add(animal);
            ArchiveChanged();
        }

        private void ArchiveChanged()
        {
            Notify();
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            var o = new Observer();

            var animal = new Subject();

            animal.Subscribe(o);

            animal.ReleaseAnimal("Caribou");

            animal.ReleaseAnimal("Ours");

            Console.ReadKey();
        }
    }
}

Façade patron de conception (facade design pattern)

Le patron de conception Façade (facade design pattern) définit une interface supérieure, qui facilite l’utilisation d’un sous-système. C’est-à-dire, la Façade offre une interface unifiée à un set des interfaces.

facade

Voici l’idée des acteurs principales :

  • Façade (Voiture application)
  • Classes d’un sous-système (Moteur, Pneus, carosserie, …)
namespace Facade
{
    /// <summary>
    /// SubClassOne
    /// </summary>
    class SubClassOne
    {
        public void MethodSubClassOne()
        {
            Console.WriteLine("Called SubClassOne");
        }
    }
    /// <summary>
    /// SubClassTwo
    /// </summary>
    class SubClassTwo
    {
        public void MethodSubClassTwo()
        {
            Console.WriteLine("Called SubClassTwo");
        }
    }
    /// <summary>
    /// Facade
    /// </summary>
    class Facade
    {
        private SubClassOne _one;
        private SubClassTwo _two;

        public Facade()
        {
            _one = new SubClassOne();
            _two = new SubClassTwo();
        }

        public void MethodeFacade()
        {
            _one.MethodSubClassOne();
            _two.MethodSubClassTwo();
        }
    }

    /// <summary>
    /// Main Program: Startup
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            var facade = new Facade();

            facade.MethodeFacade();

            Console.ReadKey();
        }
    }
}

Adapteur patron de conception (adapter pattern)

Le patron de conception Adapter est un des design patterns de GoF dans la catégorie des patrons de conception << Structural >>. C’est-à-dire, il s’agît d’un patron qui s’occupe de la composition classe objet.

Le but d’un Adapteur, c’est de convertir l’interface d’une classe en une autre interface qui est demandé par le client. L’adapteur fait des classes incompatible travailler ensemble, donc des classes qui ne peuvent pas travailler ensemble normalement.

adapter

Les acteurs principals dans ce pattern sont les suivants :

  • Target
  • Adapter
  • Adaptee
  • Client

Voici un exemple simplifié pour montrer la fonctionnalité :

namespace Adapter
{
    /// <summary>
    /// Target: defines the domain-specific interface that Client uses.
    /// </summary>
    class Target
    {
        public virtual void Request()
        {
            Console.WriteLine("Called Target");
        }
    }

    /// <summary>
    /// Adapter: adapts the interface Adaptee to the Target interface.
    /// </summary>
    /// <seealso cref="Adapter.Target" />
    class Adapter : Target
    {
        private Adaptee _adaptee = new Adaptee();

        public override void Request()
        {
            _adaptee.OtherRequest();
        }
    }

    /// <summary>
    /// Adaptee: defines an existing interface that needs adapting.
    /// </summary>
    class Adaptee
    {
        public void OtherRequest()
        {
            Console.WriteLine("Called Other");
        }
    }

    class Program
    {
        /// <summary>
        /// Client: collaborates with objects conforming to the Target interface.
        /// Mains the specified arguments.
        /// </summary>
        /// <param name="args">The arguments.</param>
        static void Main(string[] args)
        {
            var target = new Adapter();
            target.Request();

            Console.ReadKey();
        }
    }
}

 

Unit Test avec Visual Studio

C’est quoi un Unit Test ou test unitaire ? En effet, un unit test, c’est simplement du code pour tester une unité ou un bloc code sur sa fonctionnalité.

Une unité peut-être :

  • Methode
  • Property
  • Classe
  • Assembly

Pour comprendre quand on utilise les tests unitaires, on peut regarder les étapes du modèle du cycle en V,  un modèle conceptuel de gestion de projet afin d’améliorer la création d’un logiciel. Les unit tests sont donc utilisés après le codage (ou avant en utilisant TDD en fait). Les tests suivants sont les tests d’intégration, qui testent les modules indépendants du logiciel dans l’ensemble.

vmodel

NUnit et MSTest

NUnit et MSTest, sont enfin des unit testing frameworks qui sont basé sur le platform .NET et qui sont gratuit à utiliser dans le Visual Studio. Dans son solution on peut ajouter un projet test ou créer une solution avec un projet et un test projet à la fois. Pour utiliser NUnit il faut néanmoins ajouter un package NuGet dans son solution.

NUnit fournit des classes et des outils pour faciliter de créer les tests unitaires. Néanmoins il faut écrire les tests unitaires soi-même dans les langages de programmation .NET comme C# ou VB.NET…

En plus les frameworks de tests unitaires viennent avec un test runner pour voir le résultat d’un test

Voici le codage pour une classe test d’un controller dans un projet ASP.NET MVC avec MSTest qui est exécuté dans 3 étapes : Arrange, Act, Assert.

[TestClass]
public class HomeControllerTest
{
   [TestMethod]
   public void Index()
   {
      // Arrange
      HomeController controller = new HomeController();
      
      // Act
      ViewResult result = controller.Index() as ViewResult;

      // Assert
      Assert.IsNotNull(result);
   }
}

Factory patron de conception (Factory Design Pattern)

Le patron de conception Factory, l’un de GoF, a la fonctionnalité de créer  des objets. L’avantage du Factory c’est qu’on implémente une abstraction qu’isole la logique pour déterminer quelle classe sera utilisée pour créer un objet. C’est important que le patron de conception Factory utilise un interface ou une classe classe base.

factory

Voici un exemple :

namespace Factory
{
    /// <summary>
    /// Interface Animal
    /// </summary>
    interface IAnimal
    {
        string Name { get; }
    }

    /// <summary>
    /// Caribou Class
    /// </summary>
    /// <seealso cref="Factory.IAnimal" />
    class Caribou : IAnimal
    {
        public string Name
        {
            get { return "Caribou"; }
        }
    }

    /// <summary>
    /// Ours class
    /// </summary>
    /// <seealso cref="Factory.IAnimal" />
    class Ours : IAnimal
    {
        public string Name
        {
            get { return "Ours"; }
        }
    }

    /// <summary>
    /// Animal Factory
    /// </summary>
    class AnimalFactory
    {
        public static IAnimal CreateAnimal(int num)
        {
            IAnimal AnimalSelector = null;

            switch (num)
            {
                case 1:
                    AnimalSelector = new Caribou();
                    break;
                case 2:
                    AnimalSelector = new Ours();
                    break;
                default:
                    AnimalSelector = new Caribou();
                    break;
            }

            return AnimalSelector;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 3; i++)
            {
                var animal = AnimalFactory.CreateAnimal(i);
                Console.WriteLine("Id = {0}, position = {1} ", i, animal.Name);
            }

            Console.ReadKey();
        }
    }
}

Singleton patron de conception (design pattern) en C#

Le patron de conception Singleton, assure qu’une classe ne pêut que être instancié uniquement une fois et que la classe mets en place un point d’accées global.

singleton

La classe << Singleton >> défini une opération qui laisse l’accés à l’instance au client. En plus, elle est responsable pour la création et la maintenance de cette instance unique.

On utilise le singleton en général, quand

  1. on n’a qu’une seule instance et
  2. il faut gérer cette instance

En regardant l’anatomie d’une classe singleton, normalement le constructor est modifié private et l’accès public static.

Voici un exemple pour une classe Singleton, static initialization :

namespace Singleton
{
    /// <summary>
    /// Singleton class
    /// </summary>
    internal sealed class Singleton
    {
       private static Singleton _instance = null;
       

       private Singleton()
       {
       }

       public static Singleton Instantiate()
       {
          if (_instance == null)
       {
          _instance = new Singleton();
       }
          return _instance;
    }
 }

    /// <summary>
    /// Main program
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Singleton single1 = Singleton.Instanciate();
            Singleton single2 = Singleton.Instanciate();

            if (single1 == single2)
            {
                Console.WriteLine("single1 and single2 are the same instance");
            }

            Console.ReadKey();
        }
    }
}

Le problème dans cette solution << Singleton >> est que la classe singleton peut introduire des dependencies pas nécessaire et qu’elle peut être utilisé par plusieurs threads en même temps, donc elle pourrais créer plusierus instances. Par exemple dans un application Web, si il y a plusieurs HTTP requests. Un peu plus secoure c’est la façon lazy en utilisant un << thread locker >>. Dans ce cas là il faut modifier la classe sealed et référencer l’instance par le constructor.

Voici un exemple pour une classe singleton, lazy implementation .NET :

namespace Singleton
{
    /// <summary>
    /// Singleton class
    /// </summary>
    internal sealed class Singleton
    {
       private static Singleton _instance = null;
       private static readonly object _locker = new object();

    private Singleton()
    {
    }

    public static Singleton Instantiate
    {
       get
       {
          lock (_locker)
       {
          if (_instance == null)
          {
             _instance = new Singleton();
          }
       }
       return _instance;
     }
   }
 }

    /// <summary>
    /// Main program
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Singleton single1 = Singleton.Instantiate;
            Singleton single2 = Singleton.Instantiate;

            if (single1 == single2)
            {
                Console.WriteLine("single1 and single2 are the same instance");
            }

            Console.ReadKey();
        }
    }
}

Un bon exemple pour l’utilisation d’un singleton pourrais être un log file ou une classe pour configurer l’accés à un base de données. En plus on ne crée pas beaucoup des variables dans un namespace global.

Néanmoins il y a quelques désavantages, qui mettent en feu la discussion autour du patron de conception singleton:

  • n’utilise pas des abstract classes ou interfaces
  • pas de subclasses
  • difficile à tester
  • difficle de travailler parallèlement…

Quand même le singleton est souvent utilisé dans des projets grands et a sans doute une légitimation.

Design Patterns, les patrons de conception

Dans le domaine de l’informatique, et particulièrement dans le software engeneering, un << design pattern >> ou patron de conception est une solution générale ou bonne pratique en réponse à un problème habituel d’un logiciel.

Donc, un design pattern offre une solution standard qui peut être utilisé dans la conception (objet orienté) d’un logiciel. C’est-à-dire, un patron de conception a une influence sur l’architecture d’un logiciel.

Dans le livre << Design Patterns, Elements of Reusable Object-Oriented Software >> écrit par des auteurs americains, qui sont bien connu sous le nom GoF (Gang of four), il y a des différents types de design patterns :

  • Creational

Les patrons creational créent des objets pour vous, au lieu de vous laisser instancier des objets vous-même. Par exemple le Singleton pattern (unique instance of a class) ou le Factory pattern (object creats other objects).

  • Structural

Les patrons structural s’occupent d’une composition classe et objet. Ils utilisent l’inheritance et les interfaces pour créer de la nouvelle fonctionnalité. Exemple: Facade (provides a simplified interface to a large body o code) ou Adapter (makes classes with incomplete interfaces work together) pattern.

  • Behavioral

Les patrons behavioral s’occupent spécifiquement de la communication parmi les objets différents. Par exemple le Observer (used for events) ou le Strategy pattern (dependency injection).

Un aperçu de tout les patterns GoF peut être trouvé ici et puis, cette discussion sur stackoverflow montre les patrons de conception utilisés dans le codage C#.

En outre et en plus de patterns GoF, on peut jeter un coup d’oeil sur l’architecture d’une application et évoquer les patrons de conception architectural-style:

  • MVC (Model-View-Controller)
  • Repository (Seperation of concerns)
  • Service-locator (perhaps an anti-pattern, decouples classes from dependencies)

C’est aussi important, que la programmation objet orientée s’appuie sur le principe SOLID, si bien fait.

Néanmoins, malgré tout le << patron de conception >> le plus utilisé est probablement le Spaghetti code

textarea avec tinyMCE et HTML character count

Peut-être vous cherchez la fonctionnalité de compter les caractères dans votre WYSIWYG editor, où vous voulez savoir comment mettre en place un bon editor comme le tinyMCE dans votre projet ASP.NET. Alors, cet article est pour vous.

tinyMCE est probablement le meilleur editor WYSIWYG sur le marché. En plus il est distribué sous la licence Open Source LGPL 2.1 et est donc gratuit à utiliser dans votre projet commercial !

Ensuite, un character counter ou compteur de caractères. D’abord il faut se poser la question : est-ce que un compteur de caractère dans un control rich text WYSIWYG fait du sens ?

Le problème, c’est que un tel control ajoute toujours du HTML au fond. Si ce n’est pas grave, voici la solution comment implementer dans un projet ASP.NET Web Forms le tinyMCE rich text edior avec un compteur de caractères.

tinyMCE

D’abord il faut considerer qu’on s’occupe de deux scènarios différents, l’editor est un control JavaScript et est donc << rendered >> sur le client d’un autre côté ASP.NET Web Forms travaille sur le serveur et offre des controls uniquement pour Web Forms. Néanmoins on peut utiliser le control TextBox de WebForms pour créer un tinyMCE WYSIWYG editor.

Voici l’HTML :

<h1>Tiny MCE Text Editor</h1>

<asp:TextBox ID="TextBox1" runat="server" CssClass="tinymce"></asp:TextBox>

<div style="float: right;">
   Total Characters(including trails): <span id="totalChars">0</span><br />
</div>

<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /

…et le JavaScript :

<%-- tinyMCE --%>
<script>

 function setCnt(editor) {
    var content = editor.getContent({ format: 'raw' });
    var count = content.length;
    $("#totalChars").html(count);
 };

 tinymce.init({
    selector: ".tinymce",
    theme: "modern",
    encoding: "xml", // decode html tags
    forced_root_block : false,
    setup: function (editor) {
       editor.on('change', function (e) { setCnt(editor) });
       editor.on('keyup', function (e) { setCnt(editor) });
    }
 });

</script>

…enfin, le code behind :

namespace tinyMCE
{
    public partial class _Default : Page
    {

        protected void Button1_Click(object sender, EventArgs e)
        {
            var message = HttpUtility.HtmlDecode(TextBox1.Text);
        }
    }
}

Comment ajouter un répertoire existant dans un Solution Visual Studio ?

Ça arrive souvent, qu’on a on a crée une bibliothèque soi-même ou une bibliothèque est pêut-etre indisponible sur NuGet ou un autre package manager dans le Visual Studio, mais il faut l’inclure dans un solution existant.

En fait, c’est facile avec Visual Studio. Il ne faut que copier et collier un répertoire dans le répertoire, retourner au Visual Studio, pousser le bouton << show all files >> clic droit le nouveau répertoire et choisir << include in project >>. Fini.

tinymc