none
Version fonctionnellle du patron de conception Visiteur RRS feed

  • Discussion générale

  • Bonjour,

    Le patron de conception visiteur est une manière de séparer des opérations, des algorithmes d'une structure de données. Un résultat concret de cette séparation est la possibilité d'ajouter de nouvelles opérations à des structures d'objets existants, sans modifier leur structure. C'est une façon d’appliquer facilement le principe d’ouverture-fermeture.

    Ce modèle peut être
    observé dans le fonctionnement d'une compagnie de taxi. Quand une personne appelle une compagnie de taxi (en acceptant un visiteur), la société envoie un taxi au client. En entrant dans le taxi, le client (visiteur), n'est plus en contrôle de son transport, le conducteur du taxi l’est.

    J'ai écrit
    ce modèle de conception dans une version fonctionnelle (utilisation des délégués):

    using System;
     
    namespace Visitor
    {
        public delegate T VisitorFun<V, T>(V f);
     
        // Interface that is multiply inherited, and ready to accept a visitor
        public interface IFigureF
        {
            string GetName();
            int GetId();
            T Accept<T>(VisitorFun<IFigureF, T> v);
        };
     
        // Simple Figure
        public class SimpleFigureF : IFigureF
        {
            private string _name;
            private int _id;
     
            public SimpleFigureF(string name)
            {
                this._name = name;
            }
     
            public SimpleFigureF(string name, int id)
            {
                this._name = name; this._id = id;
            }
     
            public string GetName()
            {
                return this._name;
            }
     
            public int GetId()
            {
                return this._id;
            }
     
            public T Accept<T>(VisitorFun<IFigureF, T> v)
            {
                return v(this);
            }
        }
     
        // Composite Figure : array of simple figures
        public class CompositeFigureF : IFigureF
        {
            private string _name;
            private int _id;
            private IFigureF[] _figureArray;
     
            public CompositeFigureF(string name, IFigureF[] s)
            {
                this._name = name; this._figureArray = s;
            }
     
            public CompositeFigureF(string name, int id, IFigureF[] s)
            {
                this._name = name; this._id = id; this._figureArray = s;
            }
     
            public string GetName()
            {
                return this._name;
            }
     
            public int GetId()
            {
                return this._id;
            }
     
            public T Accept<T>(VisitorFun<IFigureF, T> v)
            {
                foreach (IFigureF f in _figureArray)
                {
                    f.Accept(v);
                }
                return v(this);
            }
        }
     
        class Program
        {
            // Extension by a visitor function
            public static VisitorFun<IFigureF, string> MakeNameFigureVisitorFun()
            {
                string state = string.Empty;
                return obj =>
                {
                    if (obj is SimpleFigureF)
                    {
                        state += "I am visited ! " +
                            " name = " +
                            obj.GetName() +
                            ", Id = " +
                            obj.GetId();
                        state += Environment.NewLine;
                    }
                    else if (obj is CompositeFigureF)
                    {
                        state = obj.GetName() + " / Simple Figures : \n" + state;
                    }
     
                    return state;
                };
            }
     
            static void Main(string[] args)
            {
                IFigureF Square = new SimpleFigureF("Square", 1);
                IFigureF Triangle = new SimpleFigureF("Triangle", 2);
                IFigureF Cercle = new SimpleFigureF("Cercle", 3);
                IFigureF Diamond = new SimpleFigureF("Diamond", 4);
                IFigureF[] figures = new IFigureF[4] { Square, Triangle, Cercle, Diamond };
     
                IFigureF Drawer = new CompositeFigureF("Drawer", figures);
     
                VisitorFun<IFigureF, string> f = MakeNameFigureVisitorFun();
                Console.WriteLine("{0} : {1}", Square.GetType(), Square.Accept(f));
                VisitorFun<IFigureF, string> g = MakeNameFigureVisitorFun();
                Console.WriteLine("{0} : {1}", Drawer.GetType(), Drawer.Accept(g));
            }
        }
    }           
    

     

    Vous pouvez télécharger le code source ici.

    Cordialement,


    aelassas.free.fr
    • Type modifié Link.frEditor mercredi 21 septembre 2011 10:40 Ajout d'un tuto C#
    mercredi 21 septembre 2011 10:39
    Auteur de réponse

Toutes les réponses