У кого-нибудь есть конкретный пример использования Flyweight Pattern? [закрыто]


21

Я изучал шаблоны проектирования и наткнулся на образец веса мухи. Я пытался увидеть возможности использования шаблона в своих приложениях, но у меня возникли проблемы с его отображением. Кроме того, каковы некоторые признаки того, что образец веса мухи используется, когда я читаю код других людей?

Согласно определению говорится:

Используйте общий доступ для эффективной поддержки большого количества мелкозернистых объектов.

Если я правильно понял, словари и Hashtables могут быть примерами веса мух, это правильно?

Заранее спасибо.


7
Небольшой анекдот о мухах: мне когда-то приходилось создавать большие файлы Excel (до 500 тыс. Записей, более 100 столбцов) с помощью стороннего API. Стили для ячеек стали чрезвычайно интенсивными в памяти. Таким образом, всякий раз, когда требовался стиль, проверялась хеш-таблица на предмет того, существует ли равный стиль, а затем предоставлялась просто ссылка на этот стиль. Эта модификация сделала возможным этот экспорт. На мой взгляд, обладать таким большим количеством данных в Excel - это безумие. Но у контроллеров были свои аналитические макросы, которые они хотели сохранить.
Сокол

9
Комментарий: Я надеюсь, что люди, которые пишут шаблоны и ОО-книги и статьи, приходят в реальный мир среднего программиста и перестают использовать английский в стиле юриста!
NoChance

1
«Мне когда-то приходилось создавать большие файлы Excel (до 500 тыс. Записей, более 100 столбцов)» - это не так уж много по сравнению с тем, что могут создавать некоторые трейдеры ;-)
quant_dev

После прочтения нескольких из этих примеров я думаю, что сжатие данных в памяти будет отличным местом для реализации этой техники. Спасибо за помощь!
Джереми Э

Ячейки таблицы в GWT являются маховиками.
user16764

Ответы:


19

Один пример в библиотеках Java. В Java есть примитивные типы (например int, 32-разрядное целое число) и обертки для них (например Integer, какие обертки int). Существуют методы для « вставки » intв Integerи распаковки Integerв int. Обертки необходимы, потому что примитивные типы не являются объектами и, следовательно, не могут, например, использоваться в качестве ключей в Maps или помещаться в Collections.

В методе бокса используется массив объектов flyweight в качестве своего рода кеша для Integers, соответствующих intзначениям в диапазоне от -128 до 127. Поскольку эти значения наиболее вероятно будут использоваться в качестве ключей или помещаться в коллекции, это уменьшает выделение и использование памяти. (Если есть 5000000 Integerс, представляющих значение 0, плавающее вокруг, это использует 5000000 раз больше памяти, чем повторное использование экземпляра flyweight).



1
Таким образом, внутренний пул для строк в C # является еще одним примером правильного шаблона flyweight?
Джереми Э

1
@ Джереми E: Да, по моему мнению, вы можете вызывать строки, интернирующие приложение шаблона flyweight, хотя для строк это касается не только потребления памяти, но и эффективности времени выполнения.
Сокол

Помеченные в Objective-C указатели доводят это до крайности. Целые числа в штучной упаковке до 56 бит и множество строк до шести символов даже не выделяются как объекты, но вся информация упаковывается в сам указатель объекта.
gnasher729

9

Графика. Как правило, растровое изображение (которое является основой большей части компьютерной графики потребительского уровня) является дешевым ЦП, но дорогим для работы с ним (что хорошо, потому что память дешевая, но ЦП стоит). Если это растровое изображение нужно многократно повторять при рендеринге большего пользовательского интерфейса (от значков в приложении с графическим интерфейсом Windows до символов шрифта в текстовом процессоре, до текстур на поверхностях в трехмерной игре), имеет смысл загрузить изображение в память один раз и просто указать на него, используя очень простые объекты, которые дешевы в изготовлении и сами по себе не занимают много памяти. Спрайт, который представляет собой просто точку в графическом пространстве, в которой должно отображаться изображение, представляет собой просто трехмерную точку и указатель памяти на первый пиксель изображения, которое нужно использовать. МОЖЕТ также включать в себя размеры части файла изображения спрайта, который будет использоваться, в графическом или в памяти. Эту информацию очень недорого изменить, скажем, для изменения изображения или местоположения спрайта, и это можно сделать без загрузки нового изображения каждый раз, что резко увеличивает производительность базовой программы для манипулирования и отображения соответствующих частей правильные изображения для отображения полного пользовательского интерфейса "сцены".


3

CharacterЭкземпляры ASCII-диапазона в Smalltalk - это мухи.

Когда вы оцениваете что-то вроде Character space, Character class >> #value:выполняет:

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

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

Переменная класса CharacterTableинициализируется так:

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

Таким образом, когда вы создаете строку, ASCII-диапазон Characterбудет исходить, CharacterTableа не создаваться заново каждый раз.


3

Цель использования шаблона flyweight - избежать ненужной инициализации объекта и, таким образом, сэкономить место. Как определено GOF , объект может иметь два состояния, внутреннее и внешнее:

  • Внутреннее состояние: хранится в навесном весе; он состоит из информации, которая не зависит от контекста flyweights, что делает ее доступной для совместного использования.
  • Внешнее состояние: зависит от контекста мухи и зависит от него и поэтому не может быть общим. Клиентские объекты несут ответственность за передачу внешнего состояния к весу, когда это необходимо.

Предполагая, что мы хотим разработать простое приложение для текстового редактора, в котором каждый столбец содержит все строки текста, а строка может содержать символы.

Дилемма здесь заключается в том, как создать класс Character. char cВнутри класса символов должно быть основным (внутреннее состояние) объекта. Тем не менее, символ может иметь шрифт и размер (внешнее состояние); таким образом, нам нужно сохранить его внешнее состояние в строке (клиенте) и обращаться к нему при необходимости. Для этого создаются два списка, в которых хранятся шрифты и размеры.

Следуя шаблону Flyweight, персонаж теперь можно использовать повторно, и на объекты ссылаются из определенного списка объектов (пула flyweight), который содержит все символы ASCII ( Characterобъекты).

Вот что я описал визуально:

введите описание изображения здесь

Для печати «привет» Characterнужно только 4 объекта вместо 5. После изменения шрифта новые объекты не требуются; обратите внимание, что это было бы невозможно, если бы мы сохранили внешнее состояние в классе Character, например,

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

    ....
}

Применение этого шаблона для больших наборов данных приведет к значительной оптимизации сложности памяти приложения и возможности повторного использования объектов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.