У програмуванні, легковаговик(англ. flyweight pattern) — шаблон проєктування, за яким створюється об'єкт, що мінімізує використання пам'яті розподіляючи стільки даних скільки це можливо між іншими подібними об'єктами; це спосіб використання великої кількості об'єктів, коли просте повторювання їх представлення зайняло б неприпустиму кількість пам'яті. Часто деякі частини, що зберігають стан об'єктів можуть бути спільними, і загальною практикою є тримати їх у деякий зовнішній структурі даних і передавати їх до об'єктів тимчасово коли вони використовуються.
Класичним прикладом застосування шаблону легковаговик це структури даних для графічного представлення символів при відображенні тексту. Для цього необхідно буде мати, для кожного символу в документі, об'єкт гліфу що містить контури шрифту, метрику і інші дані про форматування, але це буде займати сотні або тисячі байт для кожного символу. Замість представлення таким чином кожного символу, там можна задати посилання на легкий, щодо використання пам'яті, об'єкт із гліфом для кожного екземпляру однакового символу в документі; і в результуючому об'єкті доведеться зберігати лише тільки позицію кожного символу (в документі і/або на сторінці).
Іншим прикладом застосування цього шаблону є метод стиснення текстових рядків шляхом [en].
Призначення
Використовується для ефективної підтримки (в першу чергу для зменшення затрат пам'яті) великої кількості дрібних об'єктів.
Опис
Шаблон Легковаговик (Flyweight) використовує загальнодоступний легкий об'єкт (flyweight, легковаговик), який одночасно може використовуватися у великій кількості контекстів. Стан цього об'єкта поділяється на внутрішній, що містить інформацію, незалежну від контексту, і зовнішній, який залежить або змінюється разом з контекстом легковаговика. Об'єкти клієнтів відповідають за передачу зовнішнього стану легковаговика, коли йому це необхідно.
Переваги
- Зменшує кількість об'єктів, що підлягають обробці.
- Зменшує вимоги до пам'яті.
Недоліки
- Переміщення стану поза об'єктом розбиває інкапсуляцію та може бути менш ефективним, ніж збереження власного поля
Застосування
Шаблон Легковаговик можна використовувати коли:
- В програмі використовується велика кількість об'єктів.
- Затрати на збереження високі через велику кількість об'єктів.
- Більшість станів об'єктів можна зробити зовнішніми.
- Велика кількість груп об'єктів може бути замінена відносно малою кількістю загальнодоступних об'єктів, однократно видаливши зовнішній стан.
- Програма не залежить від ідентичності об'єктів. Оскільки об'єкти-легковаговики можуть використовуватися колективно, то тести на ідентичність будуть повертати значення "істина" ("true") для концептуально різних об'єктів.
Діаграма UML
Реалізація
C++
#include <istream> #include <string> #include <vector> #include <map> using namespace std; // моделює зображення // для простоти розуміння зображення подане пустою структурою struct Image { // тут міститься щось важке static Image load(string path) { return Image(); } }; // базовий клас для персонажів class Unit { protected: string name; float health; Image picture; }; // неправильний варіант для наглядності struct Goblin : public Unit { Goblin() { name = "Goblin"; health = 8; picture = Image::load("Goblin.jpg"); } }; struct Dragon : public Unit { Dragon() { name = "Dragon"; health = 800; picture = Image::load("Dragon.jpg"); } }; // Легковик в дії // Сховище для зображень class UnitImagesFactory { private: static map<string, Image> Images; static UnitImagesFactory uif; UnitImagesFactory() { Images["Dragon"] = Image::load("Dragon.jpg"); Images["Goblin"] = Image::load("Goblin.jpg"); } virtual ~UnitImagesFactory() {} public: static Image create_dragon_image() { return Images["Dragon"]; } static Image create_goblin_image() { return Images["Goblin"]; } }; map<string, Image> UnitImagesFactory::Images; UnitImagesFactory UnitImagesFactory::uif; // Конструктори гобліна і дракона дещо змінені для використання нашої фабрики struct BetterGoblin : public Unit { BetterGoblin() { name = "Goblin"; health = 8; picture = UnitImagesFactory::create_goblin_image(); } }; struct BetterDragon : Unit { BetterDragon() { name = "Dragon"; health = 800; picture = UnitImagesFactory::create_dragon_image(); } }; void main() { // повільне створення // зображення грузиться для кожного юніта vector<Unit *> units; for (int i = 0; i < 15; i++) { units.push_back(new Dragon()); } for (int i = 0; i < 50; i++) { units.push_back(new Goblin()); } // швидке створення // готове зображення надається усім юнітам vector<Unit *> better_units; for (int i = 0; i < 15; i++) { better_units.push_back(new BetterDragon()); } for (int i = 0; i < 50; i++) { better_units.push_back(new BetterGoblin()); } // очищаємо динамічну пам'ять for (int i = 0; i < 65; i++) { delete units[i]; } for (int i = 0; i < 65; i++) { delete better_units[i]; } }
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 Rectangle:IPolygon { float thickness; string color; float height; float width; public Rectangle(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); } } 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. }
Джерела
- (PDF) (англ.). Архів оригіналу (PDF) за 9 листопада 2012. Процитовано 16 лютого 2013.
Література
- Будай, Андрій (2012). . с. 90. Архів оригіналу за 10 жовтня 2020. Процитовано 3 січня 2018.
- Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Зноски
- . Архів оригіналу за 14 червня 2020. Процитовано 11 травня 2020.
{{}}
: Обслуговування CS1: Сторінки з текстом «archived copy» як значення параметру title () - Будай, 2012, с. 42.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
U programuvanni legkovagovik angl flyweight pattern shablon proyektuvannya za yakim stvoryuyetsya ob yekt sho minimizuye vikoristannya pam yati rozpodilyayuchi stilki danih skilki ce mozhlivo mizh inshimi podibnimi ob yektami ce sposib vikoristannya velikoyi kilkosti ob yektiv koli proste povtoryuvannya yih predstavlennya zajnyalo b nepripustimu kilkist pam yati Chasto deyaki chastini sho zberigayut stan ob yektiv mozhut buti spilnimi i zagalnoyu praktikoyu ye trimati yih u deyakij zovnishnij strukturi danih i peredavati yih do ob yektiv timchasovo koli voni vikoristovuyutsya Klasichnim prikladom zastosuvannya shablonu legkovagovik ce strukturi danih dlya grafichnogo predstavlennya simvoliv pri vidobrazhenni tekstu Dlya cogo neobhidno bude mati dlya kozhnogo simvolu v dokumenti ob yekt glifu sho mistit konturi shriftu metriku i inshi dani pro formatuvannya ale ce bude zajmati sotni abo tisyachi bajt dlya kozhnogo simvolu Zamist predstavlennya takim chinom kozhnogo simvolu tam mozhna zadati posilannya na legkij shodo vikoristannya pam yati ob yekt iz glifom dlya kozhnogo ekzemplyaru odnakovogo simvolu v dokumenti i v rezultuyuchomu ob yekti dovedetsya zberigati lishe tilki poziciyu kozhnogo simvolu v dokumenti i abo na storinci Inshim prikladom zastosuvannya cogo shablonu ye metod stisnennya tekstovih ryadkiv shlyahom en PriznachennyaVikoristovuyetsya dlya efektivnoyi pidtrimki v pershu chergu dlya zmenshennya zatrat pam yati velikoyi kilkosti dribnih ob yektiv OpisShablon Legkovagovik Flyweight vikoristovuye zagalnodostupnij legkij ob yekt flyweight legkovagovik yakij odnochasno mozhe vikoristovuvatisya u velikij kilkosti kontekstiv Stan cogo ob yekta podilyayetsya na vnutrishnij sho mistit informaciyu nezalezhnu vid kontekstu i zovnishnij yakij zalezhit abo zminyuyetsya razom z kontekstom legkovagovika Ob yekti kliyentiv vidpovidayut za peredachu zovnishnogo stanu legkovagovika koli jomu ce neobhidno PerevagiZmenshuye kilkist ob yektiv sho pidlyagayut obrobci Zmenshuye vimogi do pam yati NedolikiPeremishennya stanu poza ob yektom rozbivaye inkapsulyaciyu ta mozhe buti mensh efektivnim nizh zberezhennya vlasnogo polyaZastosuvannyaShablon Legkovagovik mozhna vikoristovuvati koli V programi vikoristovuyetsya velika kilkist ob yektiv Zatrati na zberezhennya visoki cherez veliku kilkist ob yektiv Bilshist staniv ob yektiv mozhna zrobiti zovnishnimi Velika kilkist grup ob yektiv mozhe buti zaminena vidnosno maloyu kilkistyu zagalnodostupnih ob yektiv odnokratno vidalivshi zovnishnij stan Programa ne zalezhit vid identichnosti ob yektiv Oskilki ob yekti legkovagoviki mozhut vikoristovuvatisya kolektivno to testi na identichnist budut povertati znachennya istina true dlya konceptualno riznih ob yektiv Diagrama UMLRealizaciyaC Priklad realizaciyi na movi S include lt istream gt include lt string gt include lt vector gt include lt map gt using namespace std modelyuye zobrazhennya dlya prostoti rozuminnya zobrazhennya podane pustoyu strukturoyu struct Image tut mistitsya shos vazhke static Image load string path return Image bazovij klas dlya personazhiv class Unit protected string name float health Image picture nepravilnij variant dlya naglyadnosti struct Goblin public Unit Goblin name Goblin health 8 picture Image load Goblin jpg struct Dragon public Unit Dragon name Dragon health 800 picture Image load Dragon jpg Legkovik v diyi Shovishe dlya zobrazhen class UnitImagesFactory private static map lt string Image gt Images static UnitImagesFactory uif UnitImagesFactory Images Dragon Image load Dragon jpg Images Goblin Image load Goblin jpg virtual UnitImagesFactory public static Image create dragon image return Images Dragon static Image create goblin image return Images Goblin map lt string Image gt UnitImagesFactory Images UnitImagesFactory UnitImagesFactory uif Konstruktori goblina i drakona desho zmineni dlya vikoristannya nashoyi fabriki struct BetterGoblin public Unit BetterGoblin name Goblin health 8 picture UnitImagesFactory create goblin image struct BetterDragon Unit BetterDragon name Dragon health 800 picture UnitImagesFactory create dragon image void main povilne stvorennya zobrazhennya gruzitsya dlya kozhnogo yunita vector lt Unit gt units for int i 0 i lt 15 i units push back new Dragon for int i 0 i lt 50 i units push back new Goblin shvidke stvorennya gotove zobrazhennya nadayetsya usim yunitam vector lt Unit gt better units for int i 0 i lt 15 i better units push back new BetterDragon for int i 0 i lt 50 i better units push back new BetterGoblin ochishayemo dinamichnu pam yat for int i 0 i lt 65 i delete units i for int i 0 i lt 65 i delete better units i C Priklad realizaciyi na movi S 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 Rectangle IPolygon float thickness string color float height float width public Rectangle 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 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 Priklad realizaciyi na movi 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 lt FontData WeakReference lt FontData gt gt flyweightData new WeakHashMap lt FontData WeakReference lt FontData gt gt private final int pointSize private final String fontFace private final Color color private final Set lt FontEffect gt effects private FontData int pointSize String fontFace Color color EnumSet lt FontEffect gt 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 lt FontEffect gt 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 lt FontData gt 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 amp amp other fontFace equals fontFace amp amp other color equals color amp amp 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 Dzherela PDF angl Arhiv originalu PDF za 9 listopada 2012 Procitovano 16 lyutogo 2013 LiteraturaBudaj Andrij 2012 s 90 Arhiv originalu za 10 zhovtnya 2020 Procitovano 3 sichnya 2018 Alan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5 Znoski Arhiv originalu za 14 chervnya 2020 Procitovano 11 travnya 2020 a href wiki D0 A8 D0 B0 D0 B1 D0 BB D0 BE D0 BD Cite web title Shablon Cite web cite web a Obslugovuvannya CS1 Storinki z tekstom archived copy yak znachennya parametru title posilannya Budaj 2012 s 42