Czy ktoś ma konkretny przykład użycia wzoru Flyweight? [Zamknięte]


21

Studiowałem wzorce projektowe i natrafiłem na wzór ciężaru muchy. Próbowałem dostrzec możliwości użycia wzorca w moich aplikacjach, ale mam problemy z jego użyciem. A także, jakie są pewne oznaki, że podczas odczytywania kodu innych ludzi stosowany jest wzorzec wagi muchy?

Zgodnie z definicją mówi:

Udostępnianie pozwala efektywnie obsługiwać dużą liczbę drobnoziarnistych obiektów.

Jeśli dobrze to przeczytam Słowniki i tabele skrótów mogą być przykładami ciężarów much, czy to prawda?

Z góry dziękuję.


7
Mała anegdota na temat wagi latającej: Kiedyś musiałem tworzyć duże pliki Excel (do 500 000 rekordów, ponad 100 kolumn) za pomocą interfejsu API innej firmy. Style dla komórek stały się wyjątkowo intensywne pod względem pamięci. Tak więc zawsze, gdy potrzebny był styl, sprawdzano tablicę hasht, czy istnieje już taki sam styl, a następnie podawano jedynie odniesienie do tego stylu. Ta modyfikacja umożliwiła eksport. Teraz posiadanie tak wielu danych w programie Excel jest moim zdaniem szaleństwem. Ale kontrolery miały swoje makra analityczne, które chcieli zachować.
Falcon

9
Komentarz: Mam nadzieję, że ludzie, którzy piszą wzorce, książki i artykuły OO, przyjdą do prawdziwego świata przeciętnego programisty i przestaną używać angielskiego w stylu prawnika!
NoChance

1
„Kiedyś musiałem tworzyć duże pliki Excela (do 500 000 rekordów, ponad 100 kolumn)” - to niewiele w porównaniu do tego, co niektórzy inwestorzy są w stanie stworzyć ;-)
quant_dev

Po przeczytaniu kilku z tych przykładów pomyślałbym, że kompresja danych w pamięci byłaby doskonałym miejscem do wdrożenia tej techniki. Dzięki za pomoc!
Jeremy E

Komórki tabeli w GWT to wagi latające.
user16764,

Odpowiedzi:


19

Jednym z przykładów są biblioteki Java. Java ma podstawowe typy (np. int32-bitową liczbę całkowitą) i opakowania dla nich (np. IntegerKtóre się zawija int). Istnieją metody „umieszczenia” pola intw Integeri rozpakowania pliku Integerw int. Opakowania są niezbędne, ponieważ pierwotne typy nie są obiektami, a zatem nie można ich np. Użyć jako kluczy w Maps lub umieścić w Collections.

Metoda bokserska wykorzystuje tablicę obiektów flyweight jako rodzaj pamięci podręcznej dla Integers odpowiadającej intwartościom między -128 a 127. Ponieważ są to wartości, które najprawdopodobniej zostaną użyte jako klucze lub umieszczone w kolekcjach, zmniejsza to przydział i użycie pamięci. (Jeśli 5000000 Integers reprezentuje zmienną wartość 0, to zużywa 5000000 razy więcej pamięci niż ponowne użycie instancji flyweight).



1
Więc wewnętrzna pula dla łańcuchów w C # jest kolejnym przykładem prawidłowego wzorca wagi?
Jeremy E,

1
@Jeremy E: Tak, moim zdaniem można nazwać łańcuch znaków wewnątrz aplikacji wzorca wagi lekkiej, chociaż w przypadku łańcuchów znaków nie chodzi tylko o zużycie pamięci, ale także o wydajność środowiska wykonawczego.
Falcon

Wskaźniki oznaczone w celu C doprowadzają to do skrajności. Zapakowane liczby całkowite do 56 bitów i wiele ciągów do sześciu znaków nie są nawet przydzielane jako obiekty, ale wszystkie informacje są pakowane w sam wskaźnik obiektu.
gnasher729,

9

Grafika. Zazwyczaj obraz rastrowy (który jest podstawą większości grafik komputerowych na poziomie konsumenta) jest tani w procesorze, ale wymaga dużej ilości pamięci do pracy (co jest w porządku, ponieważ pamięć jest tania, ale procesor jest drogi). Jeśli ten obraz rastrowy ma być wielokrotnie powtarzany przy renderowaniu większego interfejsu użytkownika (od ikon w aplikacji Windows GUI do znaków czcionki w edytorze tekstu, tekstur na powierzchniach w grze 3D), sensowne jest załaduj obraz raz do pamięci i po prostu wskaż go za pomocą bardzo prostych obiektów, których wykonanie jest tanie i same nie zajmują dużo pamięci. Duszek, który jest po prostu punktem w przestrzeni graficznej, w którym obraz powinien zostać wyświetlony, jest po prostu punktem 3D i wskaźnikiem pamięci do pierwszego piksela obrazu, który ma zostać użyty. MAYBE obejmuje również wymiary części pliku obrazu duszka, która ma być użyta, pod względem graficznym lub pamięciowym. Ta informacja jest bardzo niedroga do zmiany, powiedzmy, aby zmienić obraz lub lokalizację duszka, i można tego dokonać bez ładowania nowego obrazu za każdym razem, drastycznie zwiększając wydajność bazowego programu do manipulowania i wyświetlania odpowiednich części odpowiednie obrazy do renderowania kompletnej „sceny” interfejsu użytkownika.


3

CharacterInstancje o zasięgu ASCII w Smalltalk to wagi latające.

Kiedy oceniasz coś podobnego Character space, Character class >> #value:wykonuje:

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

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

Zmienna klasy CharacterTablejest inicjowana w następujący sposób:

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

Kiedy więc tworzysz Łańcuch, zakresy ASCII Characterbędą pochodzić, CharacterTablea nie być nowo tworzone za każdym razem.


3

Celem zastosowania wzorca wagi lekkiej jest uniknięcie niepotrzebnej inicjalizacji obiektu, a tym samym oszczędność miejsca. Zgodnie z definicją GOF obiekt może mieć dwa stany: wewnętrzny i zewnętrzny:

  • Stan wewnętrzny: jest przechowywany w wadze muchowej; składa się z informacji niezależnych od kontekstu wagi latającej, dzięki czemu można je udostępniać.
  • Stan zewnętrzny: zależy i zależy od kontekstu wagi muchowej, dlatego nie można się nim dzielić. Obiekty klienta są odpowiedzialne za przekazywanie stanu zewnętrznego do wagi muchowej, gdy jej potrzebuje.

Zakładając, że chcemy opracować prostą aplikację do edytowania tekstu, w której każda kolumna zawiera wszystkie wiersze tekstu, a wiersz może zawierać znaki.

Dylemat polega na tym, jak zaprojektować klasę postaci. char cW klasie znak powinien być główny (wewnętrzny stan) obiektu. Jednak znak może mieć czcionkę i rozmiar (stan zewnętrzny); dlatego musimy zapisać jego stan zewnętrzny w Row (kliencie) i uzyskać do niego dostęp w razie potrzeby. W tym celu tworzone są dwie listy przechowujące czcionki i rozmiary.

Postępując zgodnie ze wzorem Flyweight, Postać nadaje się do ponownego użycia, a obiekty są przywoływane z określonej listy obiektów (pula flyweight), która zawiera wszystkie symbole ( Characterobiekty) ASCII .

Oto, co opisałem wizualnie:

wprowadź opis zdjęcia tutaj

Do wydrukowania „cześć” Characterpotrzebne są tylko 4 obiekty zamiast 5. Po zmianie czcionki nie są wymagane żadne nowe obiekty; zauważ, że nie byłoby to możliwe, gdybyśmy zapisali stan zewnętrzny w klasie Character, np.

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

    ....
}

Zastosowanie tego wzorca do dużych zestawów danych doprowadziłoby do znacznej optymalizacji złożoności pamięci aplikacji i możliwości ponownego użycia obiektu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.