Легковаговик (шаблон проектування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Призначення[ред.ред. код]

Використовується для ефективної підтримки (в першу чергу для зменшення затрат пам'яті) великої кількості дрібних об'єктів.

Опис[ред.ред. код]

Шаблон Легковаговик (Flyweight) використовує загальнодоступний легкий об'єкт (flyweight, легковаговик), який одночасно може використовуватися у великій кількості контекстів. Стан цього об'єкта поділяється на внутрішній, що містить інформацію, незалежну від контексту, і зовнішній, який залежить або змінюється разом з контекстом легковаговика. Об'єкти клієнтів відповідають за передачу зовнішнього стану легковаговика, коли йому це необхідно.

Переваги[ред.ред. код]

  • Зменшує кількість об'єктів, що підлягають обробці.
  • Зменшує вимоги до пам'яті.

Застосування[ред.ред. код]

Шаблон Легковаговик можна використовувати коли:

  • В програмі використовується велика кількість об'єктів.
  • Затрати на збереження високі через велику кількість об'єктів.
  • Більшість станів об'єктів можна зробити зовнішніми.
  • Велика кількість груп об'єктів може бути замінена відносно малою кількістю загальнодоступних об'єктів, однократно видаливши зовнішній стан.
  • Програма не залежить від ідентичності об'єктів. Оскільки об'єкти-легковаговики можуть використовуватися колективно, то тести на ідентичність будуть повертати значення "істина" ("true") для концептуально різних об'єктів.

Діаграма UML[ред.ред. код]

Flyweight.gif

Реалізація[ред.ред. код]

Приклад C#[ред.ред. код]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
 
namespace lab2_v3
{
    class Program
    {
        static void Main()
        {
            string context="";
            LineFactory fac = new LineFactory();
            fac.GetLine(2, "red").Draw(context,14,15);
            fac.GetLine(2, "red").Draw(context, 14, 15);
            fac.GetLine(3, "blue").Draw(context,10,10);
            Console.Write(context);
 
 
 
 
            TriangleFactory fac2 = new TriangleFactory();
            fac2.GetTriangle(3, "blue").Draw("cont", 1,2,1,3,4,5);
            fac2.GetTriangle(3, "blue").Draw("cont", 2,3,4,5,6,7) ;
            fac2.GetTriangle(3, "blue").Draw("cont", 5,6,7,8,9,1);
 
            RectangleFactory fac3 = new RectangleFactory();
 
            fac3.GetRectangle(4, "red", 3, 6).Draw("cont", 3, 4);
            fac3.GetRectangle(5, "blue", 7, 8).Draw("cont", 1, 23);
            fac3.GetRectangle(5, "blue", 3, 6).Draw("cont", 1,4);
 
 
            Console.ReadKey();
        }
    }
 
   // enum typeTriangle { rectangular, isosceles, equilateral, notright };
 
 
    public interface IPolygon
    {
 
        void Draw();
    }
 
    class Line:IPolygon
    {
        float thickness;
        string color;
 
        public Line( float thickness, string color)
        {
            this.thickness = thickness;
            this.color = color;
 
        }
 
        public void Draw(string context, float x, float y)
        {
            Console.WriteLine("Line is drow!! Position x="+x +"y = "+ y);
 
        }
 
 
    }
 
    class Triangle:IPolygon 
    {
 
        float thickness;
        string color;
 
 
        public Triangle(float thickness, string color)
        {
            this.thickness = thickness;
            this.color = color;
 
 
 
        }
 
        public void Draw(string context, float x1, float y1, float x2,float y2,float x3,float y3)
        {
            Console.WriteLine( "Draw triangle! Position x1 = "+x1+"y1 = " +y1+"x2 = " + x2+ "y2 = " + y2 +"x3 = "+ x3 + "y3 = " +y3);
        }
    }  
 
    class Rektangle:IPolygon
    {
        float thickness;
        string color;
        float height;
        float width;
 
        public Rektangle(float thickness, string c, float h, float wi)
        {
            this.thickness = thickness;
            this.color = c;
            this.height = h;
            this.width = wi;
 
        }
 
        public void Draw(string context, float x1, float y1)
        {
            Console.WriteLine(" Rectangle is draw!! Position down left x1 = " + x1 + " y1 = " + y1);
        }
 
        public void Draw2() { }
 
    }
 
    class LineFactory 
    {
        private Hashtable lines = new Hashtable();
 
        public Line GetLine(float thickness, string color)
        {
            string key = color +";"+ thickness; 
            Line line = lines[key] as Line;
 
 
            if (line ==null)
            {
                line = new Line(thickness, color);
                lines.Add(key, line);
 
            }
 
            return line;
        }
    }
 
    class TriangleFactory 
    {
        private Hashtable triangles = new Hashtable();
        public Triangle GetTriangle(float thickness, string color)
        {
            string key = color + ";" + thickness ;
            Triangle triangle = triangles[key] as Triangle;
 
 
            if (triangle == null)
            {
                triangle = new Triangle(thickness, color);
 
                triangles.Add(key, triangle);
                //Console.WriteLine("Triangle done !   {0}  === ccc   {1} ==== type {2}    ", thickness, color, type);
            }
 
            return triangle;
 
        }
 
    }
 
     class RectangleFactory
     {
         private Hashtable rectangles = new Hashtable();
 
 
         public Rektangle GetRectangle(float thickness, string color, float height, float width)
         {
             string key = color + ";" + thickness +";"+height+";"+width;
             Rektangle rectangle = rectangles[key] as Rektangle;
 
 
             if (rectangle == null)
             {
                 rectangle = new Rektangle(thickness, color,height,width);
                 rectangles.Add(key, rectangle);
 
 
             }
 
             return rectangle;
 
         }
 
     }
 
}
}}

Приклад на Java[ред.ред. код]

import java.util.*;
 
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);
        effectsSet.addAll(Arrays.asList(effects));
        // 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.
}

Джерела[ред.ред. код]

Література[ред.ред. код]

Алан Шаллоуей, Джеймс Р. Тротт Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5