Flyweight Pattern'i kullanmak için belirli bir örneği olan var mı? [kapalı]


21

Tasarım kalıpları üzerinde çalışıyorum ve uç ağırlık kalıplarının karşısına geldim. Uygulamalarımda modeli kullanma fırsatlarını görmeye çalışıyorum ama nasıl kullanılacağını görmekte zorlanıyorum. Ayrıca, diğer insanların kodlarını okuduğumda uçucu ağırlık düzeninin kullanıldığına dair bazı işaretler nelerdir?

Tanıma göre diyor ki:

Çok sayıda ince taneli nesneyi verimli bir şekilde desteklemek için paylaşımı kullanın.

Doğru okuduysam, Sözlükler ve Hashtables uçucu ağırlık örnekleri olabilir, bu doğru mu?

Şimdiden teşekkürler.


7
Uçucu ağırlıklar üzerine sadece küçük bir fıkra: Bir keresinde bir 3. parti API ile büyük excel dosyaları (en fazla 500k kayıt, 100 sütun üzerinde) oluşturmak zorunda kaldım. Hücreler için olan stiller aşırı hafıza yoğunlaştı. Böylece, bir stile ihtiyaç duyulduğunda, eşit bir stile sahip olup olmadığına bakılırsa bir karma tablo kontrol edildi ve sonra bu stile yalnızca bir referans sağladı. Bu değişiklik bu ihracatı mümkün kıldı. Şimdi excel içinde bu kadar veri olması bence delilik. Ancak kontrolörlerin tutmak istedikleri analiz makroları vardı.
Şahin

9
Yorum: Desen ve OO kitapları ve makaleleri yazan kişilerin ortalama bir programcının gerçek dünyasına girip İngilizce avukat stilini kullanmayı bırakmasını umuyorum!
NoChance

1
"Bir zamanlar büyük excel dosyaları oluşturmak zorunda kaldım (en fazla 500k kayıt, 100 sütundan fazla)" - bu, bazı yatırımcıların yapabilecekleriyle karşılaştırılmaz ;-)
quant_dev

Bu örneklerin birkaçını okuduktan sonra, bellekte veri sıkıştırmanın bu tekniği uygulamak için yönetici bir yer olacağını düşünürdüm. Yardım için teşekkürler!
Jeremy E

GWT'deki tablo hücreleri uçucu ağırlıklardır.
kullanıcı16764

Yanıtlar:


19

Bir örnek Java kütüphanelerindedir. Java, ilkel türlere (örneğin int, 32 bit bir tam sayıdır) ve onlar için sarıcılara (örneğin Integersarılmış int) sahiptir. Orada "kutu" bir karşı yöntemlerdir intbir içine Integerve bir Unbox Integerbir içine int. İlkel türler nesne olmadığından ve bu nedenle örneğin Maps de s olarak yerleştirilemediğinden sararıcıları gereklidir Collection.

Boks yöntemi, -128 ile 127 arasındaki değerlere Integerkarşılık gelen s için bir önbellek türü olarak bir dizi hafif ağırlık nesnesi kullanır. intBunlar, anahtar olarak kullanılması veya koleksiyonlara yerleştirilmesi en muhtemel değerler olduğundan, tahsisat ve hafıza kullanımını azaltır. ( IntegerEtrafta yüzen 0 değerini temsil eden 5000000 s varsa , bu flyweight örneğini yeniden kullanmaktan 5000000 kat daha fazla bellek kullanır).



1
Demek ki C # 'daki stringler için intern havuzu, bir flyweight şablonunun başka bir örneği doğru mu?
Jeremy E

1
@ Jeremy E: Evet, benim görüşüme göre, sadece dizgiler için değil, aynı zamanda çalışma süresi verimi ile ilgili olarak, uçucu ağırlık modelinin bir uygulamasında staj yapan dize diyebilirsiniz.
Şahin

Objective-C etiketli işaretçiler bunu aşırı uçurur. 56 bit'e kadar olan kutulu tamsayılar ve altı karaktere kadar birçok dize, nesne olarak bile tahsis edilmez, ancak tüm bilgiler nesne işaretçisinin kendisine doldurulur.
gnasher729

9

Grafik. Tipik olarak, raster bir görüntü (çoğu tüketici seviyesi bilgisayar grafiğinin bel kemiği) CPU'dur (ucuzdur, ancak çalışmak için pahalı) (hafızası ucuzdur ancak CPU pahalıdır çünkü iyidir). Bu raster görüntü daha büyük bir kullanıcı arayüzü oluştururken defalarca tekrarlanacaksa (Windows GUI uygulamasındaki simgelerden bir kelime işlemcideki bir fontun karakterlerine, bir 3D oyunda yüzeylerdeki dokulara), çok anlamlı olur. görüntüyü bir kez belleğe yükleyin ve basitçe, yapmak için ucuz olan ve çok fazla bellek kapamayan çok basit nesneleri kullanarak işaretleyin. Bir görüntünün gösterilmesi gereken grafik alandaki bir nokta olan sprite, yalnızca görüntünün ilk pikseline yönelik bir 3D işaret ve bellek işaretçisidir. MAYBE ayrıca kullanılacak sprite görüntü dosyasının bir kısmının boyutlarını da içerir. grafiksel veya hafıza terimleriyle. Bu bilginin değiştirilmesi, örneğin, grafiğin görüntüsünü veya konumunu değiştirmek çok ucuzdur ve her seferinde yeni bir görüntü yüklemeden yapılabilir, böylece temel programın uygun bölümlerini manipüle etmek ve görüntülemek için temel programın performansını önemli ölçüde arttırır. tam bir UI "sahne" oluşturmak için uygun görüntüleri


3

CharacterSmalltalk'taki ASCII-aralığı örnekleri uçucu ağırlıklardır.

Gibi bir şey değerlendirdiğinizde Character space, Character class >> #value:yürütür:

value: anInteger 
    "Answer the Character whose value is anInteger."

    anInteger > 255 ifTrue: [^self basicNew setValue: anInteger].
    ^ CharacterTable at: anInteger + 1.

Sınıf değişkeni CharacterTableşöyle başlatılır:

initialize
    "Create the table of unique Characters, and DigitsValues."
    "Character initializeClassificationTable"

    CharacterTable ifNil: [
        "Initialize only once to ensure that byte characters are unique"
        CharacterTable := Array new: 256.
        1 to: 256 do: [:i | CharacterTable
            at: i
            put: (self basicNew setValue: i - 1)]].
    self initializeDigitValues

Bu yüzden bir String oluşturduğunuzda, ASCII serisi her seferinde yeni yaratılmak yerine Charactergelecektir CharacterTable.


3

Sineklik kalıbını kullanmanın amacı gereksiz cisim sıfırlamalarını önlemek ve böylece yerden tasarruf etmektir. GOF tarafından tanımlandığı gibi , bir nesnenin iç ve dış devlet olmak üzere iki durumu olabilir:

  • İçsel durum: Sinek ağırlığında depolanır; Uçucu ağırlıklar bağlamında bağımsız olan ve böylece paylaşılabilir kılan bilgilerden oluşur.
  • Dışsal durum: uçağın ağırlığına bağlı olarak değişir ve bu nedenle paylaşılamaz. Müşteri objeleri, ihtiyaç duyulduğunda dışsal durumun uç ağırlığa geçmesinden sorumludur.

Her sütunun metnin tüm satırlarını içerdiği ve satırın karakter içerebileceği basit bir metin düzenleyici uygulama geliştirmek istediğimizi varsayalım.

Buradaki ikilem, Character sınıfının nasıl tasarlandığıdır. char cKarakter sınıfı içinde, ana (intrinsik durum) nesne olmalıdır. Bununla birlikte, bir karakter Yazı Tipi ve Boyutuna sahip olabilir (dışsal durum); bu yüzden dışsal durumunu Row (istemci) üzerinde saklamamız ve gerektiğinde erişmemiz gerekir. Bu amaçla, Yazı Tiplerini ve Boyutları saklayan iki liste oluşturulur.

Flyweight şablonunu takip ederek, Karakter şimdi yeniden kullanılabilir ve nesnelere, tüm ASCII sembollerini ( Characternesneleri) içeren belirli bir nesne listesinden (flyweight havuzu) referansta bulunulur .

İşte görsel olarak anlattığım şey:

görüntü tanımını buraya girin

'Merhaba' yazdırmak için 5 Characteryerine yalnızca 4 nesneye ihtiyaç duyulur. Yazı tipi değiştirildiğinde, yeni nesneye gerek yoktur; Bunun dışsal durumu Character sınıfına kaydetmiş olmamızın mümkün olmayacağına dikkat edin;

class Character
{
    char c;
    int Size;
    Font font;

    ....
}

Bu kalıbı büyük veri setlerine uygulamak, uygulamanın bellek karmaşıklığı ve nesnenin yeniden kullanılabilirliği konusunda önemli optimizasyonlara yol açacaktır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.