Dans ce post, j'essaye d'apporter une solution générique au problème de gestion des statuts possibles d'un objet.
Ex : Si une barre de menus possède plusieurs boutons (1 à N), on veut qu'à un instant t, on puisse commander facilement lesquels de ces N boutons sont visibles et lesquels sont invisibles.
Beaucoup de cas sont analogues à cette problématique.
1-Pour ces N objets , créons un Enum ( ayant N valeurs possibles ):
    [Flags]
    public enum Status 
    {
        Status1 = 1,
        Status2 = 2,
        Status4 = 4,
        Status8 = 8    } 
Ici j'ai pris le cas de N = 4, la solution reste valable par récurrence.
Notez que les valeurs ne sont pas prises au hasard. (1,2,4,8....) est une suite géometrique de raison 2, le premier élément étant Math.Pow(2,0) = 1.
L'attribut [Flags] permet de faire des opérations "Binaire" sur  ces valeurs ( AND, OR, NOT,...).
2-Sur les N objets, utiliser le pattern "Decorateur" pour décorer ces objets avec une propriété supplémentaire permettant de stocker le statut associé à l'objet.
Pour simplifier , je vais simplement ajouter directement cette propriété directement à l'objet.
    public class Element
    {  
        //propriete standart
        public int Id { get; set; }   
        
        //propriétés supplémentaires 
        public Status Status { get; set; }        //permet d'attribuer un statut à l'objet
          public bool ToBeDisplay { get; set; }    //état de l'objet à l'instant T
    }
3- Sur les N objets, associez un status sur chaque objet ( relation One-To-One )
            Element e1 = new Element() { Id = 1,  Status = Status.Status1 };
            Element e2 = new Element() { Id = 2,  Status = Status.Status2 };
            Element e4 = new Element() { Id = 4,   Status = Status.Status4 };
            Element e8 = new Element() { Id = 8,  Status = Status.Status8 }; 
4- Je regroupe ensuite l'objet dans une liste
            List<Element> elements = new List<Element>();
            elements.Add(e1); 
            elements.Add(e2);
            elements.Add(e4);
            elements.Add(e8); 
5- Voici la fonction Configure qui va permettre de positionner la valeur de la propriété ToBeDisplay en fonction d'un flag entré en paramètre :
        private static List<Element>  Configure(List<Element> elts,int flag)
        {
            Status f = (Status)(Enum.Parse(typeof(Status),flag.ToString()));            
            foreach (var item in elts)
            {
                bool isToBeDisplayed = false;
                isToBeDisplayed = (item.Status & f ) == item.Status;
                item.ToBeDisplay = isToBeDisplayed;
            }
            return elts;
        }
-flag : variable de type int que l'on va caster en Status afin de pouvoir faire une opération binaire sur cette variable.
-Sur chaque élément, positionnez la propriété isToBeDisplayed .
- la ligne   isToBeDisplayed = (item.Status & f ) == item.Status; permet de jongler sur le champ Status courant de l'objet et le flag.
 Les valeurs de flag qui permettent de faire les combinaisons possibles sont sur l'intervalle: [1,Math.Pow(2,N)-1]
Dans notre cas N = 4, les valeurs de Flag intéressantes sont : 1,2,3,4,5,...15 
Voici le programme complet :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
    [Flags]
    public enum Status 
    {        
        Status1 = 1,
        Status2 = 2,
        Status4 = 4,
        Status8 = 8,
    }
    public class Element
    {        
        public Status Status { get; set; }
        public int Id { get; set; }
        public bool ToBeDisplay { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {          
            Element e1 = new Element() { Id = 1,  Status = Status.Status1 };
            Element e2 = new Element() { Id = 2, Status = Status.Status2 };
            Element e4 = new Element() { Id = 4, Status = Status.Status4 };
            Element e8 = new Element() { Id = 8, Status = Status.Status8 };
            List<Element> elements = new List<Element>();         
            elements.Add(e1); 
            elements.Add(e2);
            elements.Add(e4);
            elements.Add(e8);
            var r = Configure(elements, 7);
            foreach (var item in r)
            {
                if (item.ToBeDisplay)
                {
                    Console.WriteLine(item.Id);
                }
            }
            Console.ReadLine();
        }
        private static List<Element>  Configure(List<Element> elts,int flag)
        {
            Status f = (Status)(Enum.Parse(typeof(Status),flag.ToString()));  
            Console.WriteLine("status  =  " + f);          
            foreach (var item in elts)
            {
                bool isToBeDisplayed = false;
                isToBeDisplayed = (item.Status & f ) == item.Status;
                item.ToBeDisplay = isToBeDisplayed;
            }
            return elts;
        }
    }
} 
  
No comments:
Post a Comment