2010-01-13 3 views
1

J'ai lu que "les objets de stratégie font souvent de bons poids" (à partir de éléments de modèles de conception de logiciels orientés objet réutilisables), et je me demande comment cela peut être implémenté. Je n'ai trouvé aucun exemple sur Internet.Stratégie et Flyweight

Est-ce que le code (C#) ci-dessous est à droite, suivant cette idée?

Merci!

using System; 
using System.Collections.Generic; 

namespace StrategyFlyweight 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Client client = new Client(); 
      for(int i = 1; i <= 10;i++) 
      { 
       client.Execute(i); 
      } 
      Console.ReadKey(); 
     } 
    } 

    public interface IStrategy 
    { 
     void Check(int number); 
    } 

    public class ConcreteStrategyEven : IStrategy 
    { 
     public void Check(int number) 
     { 
      Console.WriteLine("{0} is an even number...", number); 
     } 
    } 

    public class ConcreteStrategyOdd : IStrategy 
    { 
     public void Check(int number) 
     { 
      Console.WriteLine("{0} is an odd number...", number); 
     } 
    } 

    public class FlyweightFactory 
    { 
     private Dictionary<string, IStrategy> _sharedObjects = new Dictionary<string, IStrategy>(); 

     public IStrategy GetObject(int param) 
     { 
      string key = (param % 2 == 0) ? "even" : "odd"; 

      if (_sharedObjects.ContainsKey(key)) 
       return _sharedObjects[key]; 
      else 
      { 
       IStrategy strategy = null; 
       switch (key) 
       { 
        case "even": 
         strategy = new ConcreteStrategyEven(); 
         break; 
        case "odd": 
         strategy = new ConcreteStrategyOdd(); 
         break; 
       } 
       _sharedObjects.Add(key, strategy); 
       return strategy; 
      } 
     } 
    } 

    public class Client 
    { 
     private IStrategy _strategy; 
     private FlyweightFactory _flyweightFactory = new FlyweightFactory(); 

     public void Execute(int param) 
     { 
      ChangeStrategy(param); 
      _strategy.Check(param); 
     } 

     private void ChangeStrategy(int param) 
     { 
      _strategy = _flyweightFactory.GetObject(param); 
     } 
    } 
} 

Répondre

7

Je pense que pour mettre en œuvre correctement le modèle poids plume ici, votre méthode d'usine doit toujours retourner la même instance d'une stratégie particulière (comme ConcreteStrategyEven) plutôt que de construire une nouvelle instance à chaque fois. Si je ne me trompe pas, le point de dire que les objets Stratégie font de bons Flyweights est qu'ils n'encapsulent souvent aucun état (puisqu'ils représentent des algorithmes plutôt que des entités) et peuvent être réutilisés.

Voici un lien vers un exemple d'usine Flyweight: http://www.java2s.com/Code/Java/Design-Pattern/FlyweightFactory.htm. Notez cette partie, notamment:

public synchronized FlyweightIntr getFlyweight(String divisionName) { 
    if (lstFlyweight.get(divisionName) == null) { 
     FlyweightIntr fw = new Flyweight(divisionName); 
     lstFlyweight.put(divisionName, fw); 
     return fw; 
    } else { 
     return (FlyweightIntr) lstFlyweight.get(divisionName); 
    } 
    } 

Ici, dans la méthode de l'usine, une nouvelle FlyweightIntr est initialisées si le bon est pas disponible; sinon, il est récupéré à partir de lstFlyweight.

+0

C'est ce que ce bit fait, non? 'if (_sharedObjects.ContainsKey (key)) retourne _sharedObjects [clé];' C'est certainement une initialisation paresseuse/singleton là. –

+0

Ah, tu as raison - quand je l'ai lu la première fois, j'ai pensé que 'key' était l'entier et il était en train d'initialiser une nouvelle stratégie pour chacun d'entre eux. Eh bien, j'espère que ma réponse a été utile/informative de toute façon. – danben

+0

oui, c'était, merci – Fabio