Pehelysúlyú programtervezési minta

A számítástudományban a pehelysúlyú programtervezési minta, pehelysúlyú tervezési minta, vagy pehelysúlyú minta egy programtervezési minta. A pehelysúlyú objektum egy olyan objektum, amely minimalizálja memóriahasználatot azzal, hogy annyi adatot oszt meg, amennyi csak lehetséges más hasonló objektumokkal. Ez a nagyszámú objektumok használatának az a módja, mikor egy egyszerű ismételt reprezentáció használna fel el nem fogadható mennyiségű memóriát. Gyakran az objektum állapotának egyes részei megoszthatók, gyakorlatilag külső adatstruktúrákban tároljuk őket, és csak ideiglenesen adjuk át a pehelysúlyú objektumoknak a felhasználás során.

Egy klasszikus példa a pehelysúlyú minta használatára egy szövegszerkesztőben a karakterek grafikus reprezentációja. Kívánatos lenne, hogy egy dokumentumban minden karakter egy olyan írásjel objektum lenne, amely tartalmazza a font típusát, méretét, és más a kinézetével kapcsolatos adatot, de ez akár száz vagy ezer bájt is lehet karakterenként. E helyett minden karakterhez lenne egy referencia egy megosztott pehelysúlyú írásjel objektum, egy fajta karakternek minden példánya ugyanarra az objektumra mutatna a dokumentumban; plusz még minden karakter elhelyezkedését (a dokumentumban vagy az oldalon) kellene tárolni belsőleg az objektumban.

Egy másik példa a string internálás.

Más szövegkörnyezetben az identikus adatstruktúrák ötletét hash consing-nak is hívják.

Története

A Programtervezési minták: Újrafelhasználható objektumorientált szoftver elemei tankönyv szerint[1] a pehelysúlyú mintát először Paul Calder és Mark Linton 1990-ben alkotta meg és vizsgálta teljeskörűen, hogy hatékonyan tudja kezelni az írásjel információkat egy WYSIWYG szövegszerkesztőben,[2] habár hasonló technikákat már használtak más rendszerekben pl. a Weinand alkalmazás keretrendszerben (1988).[3]

Állandóság és egyenlőség

Azért, hogy lehetővé tegyük a pehelysúlyú objektumok biztonságos megosztást a kliensek és szálak között az objektumoknak megváltozhatatlannak kell lenniük. A pehelysúlyú objektumok definíció szerint értékkel rendelkező objektumok (angolul value objects). Ugyanannak az értéknek a két pehelysúlyú példányát azonosnak lehet tekinteni.

Lássuk például a C#-ban a következőt (operátor override ill. overloading):

public class CoffeeFlavour {
    private readonly string _flavour;

    public CoffeeFlavour(string flavour) {
        _flavour = flavour;
    }

    public string Flavour {
        get { return _flavour; }
    }

    public override bool Equals(object obj) {
        if (ReferenceEquals(null, obj)) return false;
        return obj is CoffeeFlavour && Equals((CoffeeFlavour)obj);
    }

    public bool Equals(CoffeeFlavour other) {
        return string.Equals(_flavour, other._flavour);
    }

    public override int GetHashCode() {
        return (_flavour != null ? _flavour.GetHashCode() : 0);
    }

    public static bool operator ==(CoffeeFlavour a, CoffeeFlavour b) {
        return Equals(a, b);
    }

    public static bool operator !=(CoffeeFlavour a, CoffeeFlavour b) {
        return !Equals(a, b);
    }
}

Párhuzamosság

Külön figyelmet kell fordítani a több szálon létrejövő pehelysúlyú objektumok esetére.

Ha az értékek listája előre ismert és véges, a pehelysúlyú komponensek idő előtt példányosíthatók és elkérhetők egy többszálú konténertől a versenyhelyzet nélkül. Ebben az esetben két lehetőségünk van:

  1. A pehelysúlyú komponens példányosítása egyszálú, bevezetve a versenyhelyzetet és biztosítva az egy példányonkénti egy értéket.
  2. A párhuzamos szálaknak megengedni, hogy készítsenek számos pehelysúlyú példányt, amely megszünteti a versenyhelyzetet és engedélyez több példányt értékenként. Ez a lehetőség csak akkor életképes, ha az egyenlőség kritériuma biztosított.

C# példa

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;

public interface ICoffeeFlavourFactory {
    CoffeeFlavour GetFlavour(string flavour);
}

public class ReducedMemoryFootprint : ICoffeeFlavourFactory {
    private readonly object _cacheLock = new object();
    private readonly IDictionary<string, CoffeeFlavour> _cache = new Dictionary<string, CoffeeFlavour>();

    public CoffeeFlavour GetFlavour(string flavour) {
        if (_cache.ContainsKey(flavour)) return _cache[flavour];
        var coffeeFlavour = new CoffeeFlavour(flavour);
        ThreadPool.QueueUserWorkItem(AddFlavourToCache, coffeeFlavour);
        return coffeeFlavour;
    }

    private void AddFlavourToCache(object state) {
        var coffeeFlavour = (CoffeeFlavour)state;
        if (!_cache.ContainsKey(coffeeFlavour.Flavour)) {
            lock (_cacheLock) {
                if (!_cache.ContainsKey(coffeeFlavour.Flavour)) _cache.Add(coffeeFlavour.Flavour, coffeeFlavour);
            }
        }
    }
}

public class MinimumMemoryFootprint : ICoffeeFlavourFactory {
    private readonly ConcurrentDictionary<string, CoffeeFlavour> _cache = new ConcurrentDictionary<string, CoffeeFlavour>();

    public CoffeeFlavour GetFlavour(string flavour) {
        return _cache.GetOrAdd(flavour, flv => new CoffeeFlavour(flv));
    }
}

Egyszerű megvalósítás

A pehelysúlyú minta lehetővé teszi azon nagyméretű adatok megosztását, amelyek közösek minden objektumban. Más szavakkal, ha azt gondoljuk, hogy ugyanaz az adat ismétlődik minden objektumban, akkor érdemes használni ezt a mintát, egy mutatóval egy egyszerű objektumra mellyel egyszerűen helyet takarítunk meg. Jelen esetben a FlyweightPointer létrehoz egy statikus Company tagot, amely a MyObject minden példányában használható.

//IVSR: simple flyweight example in C#
    // Defines Flyweight object which repeats itself.
    public class FlyWeight
    {
        public string Company { get; set; }
        public string CompanyLocation { get; set; }
        public string CompanyWebSite { get; set; }
        //Bulky Data
        public byte[] CompanyLogo { get; set; } 
    }
    public static class FlyWeightPointer
    {
        public static FlyWeight Company = new FlyWeight
        {
            Company = "Abc",
            CompanyLocation = "XYZ",
            CompanyWebSite = "www.abc.com"
        };
    }
    public class MyObject
    {
        public string Name { get; set; }
        public FlyWeight Company
        {
            get
            {
                return FlyWeightPointer.Company;
            }
        }
    }

Java példa

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// Instances of CoffeeFlavour will be the Flyweights
class CoffeeFlavour {
  private final String name;

  CoffeeFlavour(String newFlavor) {
    this.name = newFlavor;
  }

  @Override
  public String toString() {
    return name;
  }
}

// Menu acts as a factory and cache for CoffeeFlavour flyweight objects
class Menu {
  private Map<String, CoffeeFlavour> flavours = new HashMap<String, CoffeeFlavour>();

  CoffeeFlavour lookup(String flavorName) {
    if (!flavours.containsKey(flavorName))
      flavours.put(flavorName, new CoffeeFlavour(flavorName));
    return flavours.get(flavorName);
  }

  int totalCoffeeFlavoursMade() {
    return flavours.size();
  }
}

class Order {
  private final int tableNumber;
  private final CoffeeFlavour flavour;

  Order(int tableNumber, CoffeeFlavour flavor) {
    this.tableNumber = tableNumber;
    this.flavour = flavor;
  }

  void serve() {
    System.out.println("Serving " + flavour + " to table " + tableNumber);
  }
}

public class CoffeeShop {
  private final List<Order> orders = new ArrayList<Order>();
  private final Menu menu = new Menu();

  void takeOrder(String flavourName, int table) {
    CoffeeFlavour flavour = menu.lookup(flavourName);
    Order order = new Order(table, flavour);
    orders.add(order);
  }
  
  void service() {
    for (Order order : orders)
      order.serve();    
  }
  
  String report() {
    return "\ntotal CoffeeFlavour objects made: "
        + menu.totalCoffeeFlavoursMade();
  }

  public static void main(String[] args) {
    CoffeeShop shop = new CoffeeShop();

    shop.takeOrder("Cappuccino", 2);
    shop.takeOrder("Frappe", 1);
    shop.takeOrder("Espresso", 1);
    shop.takeOrder("Frappe", 897);
    shop.takeOrder("Cappuccino", 97);
    shop.takeOrder("Frappe", 3);
    shop.takeOrder("Espresso", 3);
    shop.takeOrder("Cappuccino", 3);
    shop.takeOrder("Espresso", 96);
    shop.takeOrder("Frappe", 552);
    shop.takeOrder("Cappuccino", 121);
    shop.takeOrder("Espresso", 121);

    shop.service();
    System.out.println(shop.report());
  }
}

Ruby példa

# Flyweight Object
class Lamp
  attr_reader :color
  #attr_reader makes color attribute available outside 
  #of the class by calling .color on a Lamp instance

  def initialize(color)
    @color = color
  end
end

class TreeBranch
  def initialize(branch_number)
    @branch_number = branch_number
  end

  def hang(lamp)
    puts "Hang #{lamp.color} lamp on branch #{@branch_number}"
  end
end

# Flyweight Factory
class LampFactory
  def initialize
    @lamps = {}
  end

  def find_lamp(color)
    if @lamps.has_key?(color)
      # if the lamp already exists, reference it instead of creating a new one
      lamp = @lamps[color]
    else
      lamp = Lamp.new(color)
      @lamps[color] = lamp
    end
    lamp
  end

  def total_number_of_lamps_made
    @lamps.size
  end
end

class ChristmasTree
  def initialize
    @lamp_factory = LampFactory.new
    @lamps_hung = 0

    dress_up_the_tree
  end

  def hang_lamp(color, branch_number)
    TreeBranch.new(branch_number).hang(@lamp_factory.find_lamp(color))
    @lamps_hung += 1
  end

  def dress_up_the_tree
    hang_lamp('red', 1)
    hang_lamp('blue', 1)
    hang_lamp('yellow', 1)
    hang_lamp('red', 2)
    hang_lamp('blue', 2)
    hang_lamp('yellow', 2)
    hang_lamp('red', 3)
    hang_lamp('blue', 3)
    hang_lamp('yellow', 3)
    hang_lamp('red', 4)
    hang_lamp('blue', 4)
    hang_lamp('yellow', 4)
    hang_lamp('red', 5)
    hang_lamp('blue', 5)
    hang_lamp('yellow', 5)
    hang_lamp('red', 6)
    hang_lamp('blue', 6)
    hang_lamp('yellow', 6)
    hang_lamp('red', 7)
    hang_lamp('blue', 7)
    hang_lamp('yellow', 7)
    puts "Made #{@lamp_factory.total_number_of_lamps_made} total lamps"
  end
end

Fordítás

Ez a szócikk részben vagy egészben a Flyweight pattern című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

Kapcsolódó szócikkek

Jegyzetek

  1. Gamma, Erich, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 205–206. o. (1995). ISBN 0-201-63361-2 
  2. Calder, Paul R. (1990. október 1.). „Glyphs: Flyweight Objects for User Interfaces”. The 3rd Annual ACM SIGGRAPH Symposium on User Interface Software and Technology: 92–101. doi:10.1145/97924.97935. 
  3. Weinand, Andre (1988). „ET++—an object oriented application framework in C++”. OOPSLA (Object-Oriented Programming Systems, Languages and Applications): 46–57. doi:10.1145/62083.62089. 

Read other articles:

Cette page concerne l'année 1862 (MDCCCLXII en chiffres romains) du calendrier grégorien. Chronologies 5 mai : siège de Puebla.Données clés 1859 1860 1861  1862  1863 1864 1865Décennies :1830 1840 1850  1860  1870 1880 1890Siècles :XVIIe XVIIIe  XIXe  XXe XXIeMillénaires :-Ier Ier  IIe  IIIe Chronologies géographiques Afrique Afrique du Sud, Algérie, Angola, Bénin, Botswana, Burkina Faso, Burundi, Cameroun, Cap-Vert, Rép...

 

Begonia miranda TaksonomiDivisiTracheophytaSubdivisiSpermatophytesKladAngiospermaeKladmesangiospermsKladeudicotsKladcore eudicotsKladSuperrosidaeKladrosidsKladfabidsOrdoCucurbitalesFamiliBegoniaceaeGenusBegoniaSpesiesBegonia miranda Irmsch., 1951 lbs Begonia miranda adalah spesies tumbuhan yang tergolong ke dalam famili Begoniaceae. Spesies ini juga merupakan bagian dari ordo Cucurbitales. Nama ilmiah spesies ini pertama kali diterbitkan oleh Edgar Irmscher pada 1951. Referensi Pranala luar B...

 

American multinational home improvement supplies retailing company The Home Depot, Inc.Company typePublicTraded asNYSE: HDDJIA componentS&P 100 componentS&P 500 componentIndustryRetailingFoundedFebruary 6, 1978; 46 years ago (1978-02-06) in Marietta, Georgia, U.S.FoundersBernard MarcusArthur BlankRon BrillPat FarrahKen LangoneHeadquartersUnincorporated Cobb County, Georgia, U.S.Number of locations2,335 (January 2024)Areas servedUnited StatesPuerto Rico (since 19...

Korps Wanita Angkatan Darat(Kowad)Lambang Korps Wanita TNI ADDibentuk22 Desember 1961NegaraIndonesiaBagian dariTNI Angkatan DaratMotoDharma PusphaSitus webwww.tniad.mil.id Korps Wanita Angkatan Darat atau di singkat (Kowad) Pembentukan Korps Wanita Angkatan Darat diilhami oleh hasil perjuangan para Pahlawan Wanita Indonesia yang ikut serta menegakkan kemerdekaan Indonesia dan usaha para pendahulu untuk meraih kemajuan bagi kaum wanita. Untuk itu pada tahun 1959 Asisten 3 personel Kasad Kolone...

 

Questa voce sull'argomento centri abitati del Lubusz è solo un abbozzo. Contribuisci a migliorarla secondo le convenzioni di Wikipedia. Torzymcomune LocalizzazioneStato Polonia Voivodato Lubusz Distretto Sulęcin AmministrazioneSindacoRyszard Stanulewicz TerritorioCoordinate52°18′46″N 15°04′40″E / 52.312778°N 15.077778°E52.312778; 15.077778 (Torzym)Coordinate: 52°18′46″N 15°04′40″E / 52.312778°N 15.077778°E52.31277...

 

Species of mammal (mustelid) This article is about the animal. For the sewing stitch, see Stoating. For other uses, see Ermine (disambiguation). Stoat Conservation status Least Concern  (IUCN 3.1)[1] Scientific classification Domain: Eukaryota Kingdom: Animalia Phylum: Chordata Class: Mammalia Order: Carnivora Family: Mustelidae Genus: Mustela Species: M. erminea Binomial name Mustela ermineaLinnaeus, 1758 Stoat range (includes M. richardsonii and M. haidarum)   na...

Road in Kolkata, India Eastern Metropolitan BypassEM BypassEM Bypass with under-construction ramp of Parama Island FlyoverMaintained byKolkata Metropolitan Development AuthorityLength32 km (20 mi)LocationGreater Kolkata (Kolkata district and South 24 Parganas district), IndiaNearest Kolkata Metro stationBengal Chemical and Salt Lake Stadium (Kolkata Metro Line 2); Beliaghata (under construction) to Satyajit Ray (under construction) (Kolkata Metro Line 6)North endUltadangaSouth...

 

Mountain peak in Oregon Hillman PeakSoutheast aspectHighest pointElevation8,151 ft (2,484 m)[1]Prominence1,391 ft (424 m)[1]Parent peakMount Scott (8,934 ft)[2]Isolation8.01 mi (12.89 km)[2]Coordinates42°57′07″N 122°10′09″W / 42.9518305°N 122.1692692°W / 42.9518305; -122.1692692[3]NamingEtymologyJohn Wesley HillmanGeographyHillman PeakLocation in OregonShow map of OregonHillman PeakH...

 

Taiwanese political party established in 2019 Not to be confused with Taiwanese People's Party (1927–1931). Taiwan People's Party 台灣民眾黨AbbreviationTPPChairmanKo Wen-jeSecretary-GeneralVincent Chou [zh]FounderKo Wen-jeFounded6 August 2019 (2019-08-06)HeadquartersNo. 27, Section 1, Hangzhou South Road, Zhongzheng District, Taipei City, TaiwanMembership (2023) 32,500[1]IdeologyCivic nationalism[2]Social liberalism[3]Populism[4&#...

В статье есть список источников, но не хватает сносок. Без сносок сложно определить, из какого источника взято каждое отдельное утверждение. Вы можете улучшить статью, проставив сноски на источники, подтверждающие информацию. Сведения без сносок могут быть удалены. (8 дек...

 

此條目可参照英語維基百科相應條目来扩充。 (2021年5月6日)若您熟悉来源语言和主题,请协助参考外语维基百科扩充条目。请勿直接提交机械翻译,也不要翻译不可靠、低品质内容。依版权协议,译文需在编辑摘要注明来源,或于讨论页顶部标记{{Translated page}}标签。 约翰斯顿环礁Kalama Atoll 美國本土外小島嶼 Johnston Atoll 旗幟颂歌:《星條旗》The Star-Spangled Banner約翰斯頓環礁�...

 

Bài viết này cần thêm chú thích nguồn gốc để kiểm chứng thông tin. Mời bạn giúp hoàn thiện bài viết này bằng cách bổ sung chú thích tới các nguồn đáng tin cậy. Các nội dung không có nguồn có thể bị nghi ngờ và xóa bỏ. Ngân Hàng Nhà nước Việt Nam Đối với các định nghĩa khác, xem Ngân hàng (định hướng). Tài chính Thị trường tài chính Thị trường trái phiếu Thị trường hàng hóa Th�...

2020年夏季奥林匹克运动会波兰代表團波兰国旗IOC編碼POLNOC波蘭奧林匹克委員會網站olimpijski.pl(英文)(波兰文)2020年夏季奥林匹克运动会(東京)2021年7月23日至8月8日(受2019冠状病毒病疫情影响推迟,但仍保留原定名称)運動員206參賽項目24个大项旗手开幕式:帕维尔·科热尼奥夫斯基(游泳)和马娅·沃什乔夫斯卡(自行车)[1]闭幕式:卡罗利娜·纳亚(皮划艇)&#...

 

American baseball player (born 1988) Baseball player Andrew LamboLambo with the Great Lakes Loons in 2008Outfielder/First basemanBorn: (1988-08-11) August 11, 1988 (age 35)Newbury Park, California, U.S.Batted: LeftThrew: LeftMLB debutAugust 13, 2013, for the Pittsburgh PiratesLast MLB appearanceApril 7, 2016, for the Oakland AthleticsMLB statisticsBatting average.189Hits18Home runs1Runs batted in3 Teams Pittsburgh Pirates (2013–2015) Oakland Athletics (201...

 

2017 British nature documentary television series Blue Planet IIGenreNature documentaryPresented byDavid AttenboroughComposers Hans Zimmer David Fleming Jacob Shea Country of originUnited KingdomOriginal languageEnglishNo. of episodes7ProductionExecutive producers James Honeyborne Mark Brownlow Producers Miles Barton Orla Doherty Kathryn Jeffs Will Ridgeon John Ruthven Jonathan Smith Running time60 minutesProduction companies BBC Natural History Unit BBC Studios The Open University BBC Americ...

Historical state in the Arabian Peninsula from 1633 to 1934 Principality of Najran1633–1934 FlagNajran (lime, down south) in Arabia in 1918.CapitalNajranCommon languagesArabicReligion Ismaili Shia IslamGovernmentPrincipalityDa'i • 1677–1717 Muhammad ibn Isma'il Al Makrami[1]• 1912–1934 Ali bin Muhsin Al Shibami[2] History • Established 1633• Disestablished 1934 Preceded by Succeeded by Yemeni Zaidi State Saudi Arabia Today part ...

 

ピタゴラスの定理 種類 定理分野 ユークリッド幾何学命題 2辺 (a, b) 上の2つの正方形の面積の和は、斜辺 (c) 上の正方形の面積に等しくなる。数式 a 2 + b 2 = c 2 {\displaystyle a^{2}+b^{2}=c^{2}} 一般化 余弦定理 空間幾何学 非ユークリッド幾何学 微分幾何学 結果 ピタゴラス数 逆ピタゴラスの定理 複素数 ユークリッド距離 ピタゴラスの三角恒等式 初等幾何学におけるピタゴラ�...

 

هنيكل إتش إي 111معلومات عامةالنوع قاذفة قنابلبلد الأصل  ألمانيا التطوير والتصنيعالصانع هاينكلسنة الصنع 1935الكمية المصنوعة 32سيرة الطائرةدخول الخدمة 1935انتهاء الخدمة 1945أول طيران 24 فبراير 1935الوضع الحالي منتهية الخدمةالخدمةالمستخدم الأساسي سلاح الجو الألمانيالخصائصالطو�...

Graphic used in United Kingdom election broadcasts A view of the swingometer graphics used for the 2005 general election campaign The swingometer is a graphics device that shows the effects of the swing from one party to another on British election results programmes.[1] It is used to estimate the number of seats that will be won by different parties, given a particular national swing (in percentage points) in the vote towards or away from a given party, and assuming that that percent...

 

Tour Down Under 2020 GénéralitésCourse22e Tour Down UnderCompétitionUCI World Tour 2020 2.UWTÉtapes6Dates21 – 26 janvier 2020Distance870,2 kmPays AustralieLieu de départTanundaLieu d'arrivéeWillunga HillÉquipes20Partants140Arrivants132Vitesse moyenne42,204 km/hSite officielSite officielRésultatsVainqueur Richie Porte (Trek-Segafredo)Deuxième Diego Ulissi (UAE Team Emirates)Troisième Simon Geschke (CCC Team)Classement par points Jasper Philipsen (UAE Team Emirates)Meilleur grimpeu...