Приспособленец (шаблон проектирования)

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску

Шаблон Flyweight (Приспособленец) используется для уменьшения затрат при работе с большим количеством мелких объектов.

Цель

Уменьшение количества объектов структуры, имеющих общую сущность, путем использования сущности одного экземпляра.

Описание

Файл:Flyweight.gif

Примеры

Пример на Java

<source lang="java"> public enum FontEffect {

   BOLD, ITALIC, SUPERSCRIPT, SUBSCRIPT, STRIKETHROUGH

}

public final class FontData {

   /**
    * A weak hash map will drop unused references to FontData.
    * Values have to be wrapped in WeakReferences, 
    * because value objects in weak hash map are held by strong references.
    */
   private static final WeakHashMap<FontData, WeakReference<FontData>> flyweightData =
       new WeakHashMap<FontData, WeakReference<FontData>>();
   private final int pointSize;
   private final String fontFace;
   private final Color color;
   private final Set<FontEffect> effects;
   private FontData(int pointSize, String fontFace, Color color, EnumSet<FontEffect> effects) {
       this.pointSize = pointSize;
       this.fontFace = fontFace;
       this.color = color;
       this.effects = Collections.unmodifiableSet(effects);
   }
   public static FontData create(int pointSize, String fontFace, Color color,
       FontEffect... effects) {
       EnumSet<FontEffect> effectsSet = EnumSet.noneOf(FontEffect.class);
       for (FontEffect fontEffect : effects) {
           effectsSet.add(fontEffect);
       }
       // We are unconcerned with object creation cost, we are reducing overall memory consumption
       FontData data = new FontData(pointSize, fontFace, color, effectsSet);
       if (!flyweightData.containsKey(data)) {
           flyweightData.put(data, new WeakReference<FontData> (data));
       }
       // return the single immutable copy with the given values
       return flyweightData.get(data).get();
   }
   @Override
   public boolean equals(Object obj) {
       if (obj instanceof FontData) {
           if (obj == this) {
               return true;
           }
           FontData other = (FontData) obj;
           return other.pointSize == pointSize && other.fontFace.equals(fontFace)
               && other.color.equals(color) && other.effects.equals(effects);
       }
       return false;
   }
   @Override
   public int hashCode() {
       return (pointSize * 37 + effects.hashCode() * 13) * fontFace.hashCode();
   }
   // Getters for the font data, but no setters. FontData is immutable.

} </source>

Пример на C#

<source lang="csharp"> using System; using System.Collections;

namespace Flyweight {

 class MainApp
 {
   static void Main()
   {
     // Build a document with text
     string document = "AAZZBBZB";
     char[] chars = document.ToCharArray();
     CharacterFactory f = new CharacterFactory();
     // extrinsic state
     int pointSize = 10;
     // For each character use a flyweight object
     foreach (char c in chars)
     {
       pointSize++;
       Character character = f.GetCharacter(c);
       character.Display(pointSize);
     }
     // Wait for user
     Console.Read();
   }
 }
 // "FlyweightFactory"
 class CharacterFactory
 {
   private Hashtable characters = new Hashtable();
   public Character GetCharacter(char key)
   {
     // Uses "lazy initialization"
     Character character = characters[key] as Character;
     if (character == null)
     {
       switch (key)
       {
         case 'A': character = new CharacterA(); break;
         case 'B': character = new CharacterB(); break;
           //...
         case 'Z': character = new CharacterZ(); break;
       }
       characters.Add(key, character);
     }
     return character;
   }
 }
 // "Flyweight"
 abstract class Character
 {
   protected char symbol;
   protected int width;
   protected int height;
   protected int ascent;
   protected int descent;
   protected int pointSize;
   public abstract void Display(int pointSize);
 }
 // "ConcreteFlyweight"
 class CharacterA : Character
 {
   // Constructor
   public CharacterA()
   {
     this.symbol = 'A';
     this.height = 100;
     this.width = 120;
     this.ascent = 70;
     this.descent = 0;
   }
   public override void Display(int pointSize)
   {
     this.pointSize = pointSize;
     Console.WriteLine(this.symbol +
       " (pointsize " + this.pointSize + ")");
   }
 }
 // "ConcreteFlyweight"
 class CharacterB : Character
 {
   // Constructor
   public CharacterB()
   {
     this.symbol = 'B';
     this.height = 100;
     this.width = 140;
     this.ascent = 72;
     this.descent = 0;
   }
   public override void Display(int pointSize)
   {
     this.pointSize = pointSize;
     Console.WriteLine(this.symbol +
       " (pointsize " + this.pointSize + ")");
   }
 }
 // ... C, D, E, etc.
 // "ConcreteFlyweight"
 class CharacterZ : Character
 {
   // Constructor
   public CharacterZ()
   {
     this.symbol = 'Z';
     this.height = 100;
     this.width = 100;
     this.ascent = 68;
     this.descent = 0;
   }
   public override void Display(int pointSize)
   {
     this.pointSize = pointSize;
     Console.WriteLine(this.symbol +
       " (pointsize " + this.pointSize + ")");
   }
 }

} </source>

Пример на C++

<source lang="cpp">

  1. include <map>
  2. include <iostream>

// "Flyweight" class Character { public: virtual void display() const = 0;

protected: char mSymbol; int mWidth ,mHeight ,mAscent ,mDescent ,mPointSize ; };

// "ConcreteFlyweight" class ConcreteCharacter : public Character { public: // Constructor ConcreteCharacter( const char aSymbol, int aPointSize ) { mSymbol = aSymbol; mHeight = 100; mWidth = 120; mAscent = 70; mDescent = 0; mPointSize = aPointSize; }

// from Character virtual void display() const { std::cout << mSymbol << " ( PointSize " << mPointSize << " )\n"; } };


// "FlyweightFactory" template< int POINT_SIZE = 10 > class CharacterFactory {

public: const Character& getCharacter( const char aKey ) {

// Uses "lazy initialization" Character* character = NULL; Characters::iterator it = mCharacters.find( aKey );


if ( mCharacters.end() == it ) { switch (aKey) { case 'A': character = new ConcreteCharacter('A', POINT_SIZE); break; case 'B': character = new ConcreteCharacter('B', POINT_SIZE); break; //... case 'Z': character = new ConcreteCharacter('Z', POINT_SIZE); break; default: character = new ConcreteCharacter('-', POINT_SIZE); break; } mCharacters.insert( make_pair( aKey, character ) ); } else { character = it->second; }

return *character; }

private: typedef std::map< char, Character* > Characters; Characters mCharacters; };


int main() { std::string document = "AAZZBBZB";

CharacterFactory<12> characterFactory;

std::string::const_iterator it = document.begin(); while( document.end() != it ) { const Character& character = characterFactory.getCharacter( *it++ ); character.display(); } return 0; }

</source>



структурные шаблоны проектирования

адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных

bg:Миниобект (шаблон) cs:Flyweight de:Flyweight en:Flyweight pattern es:Flyweight (patrón de diseño) fr:Poids-mouche (patron de conception) it:Flyweight pattern ja:Flyweight パターン ko:플라이웨이트 패턴 pl:Pyłek (wzorzec projektowy) pt:Flyweight uk:Легковаговик (шаблон проектування) vi:Flyweight pattern

Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....