Flyweight
От: ssm Россия  
Дата: 13.07.04 08:13
Оценка: :))
Добрый день,
немог бы кто-то доступно объяснить о использовании паттерна Flyweight? Перечитал вчера 3 раза в "паттернах проектирования", но так до конца не понял предлагаемой реализации. Контекст применения понятен, а вот реализация приведена какая-то ...
Буду рад простому примеру для тех кто в башне танка с минимом объяснения.
Тройки готовы к раздаче
Спасибо

17.07.04 00:48: Перенесено модератором из 'C/C++'. _AK_ (3) в Проектирование — Павел Кузнецов
Re: Flyweight
От: ssm Россия  
Дата: 13.07.04 10:34
Оценка: :))
Здравствуйте, ssm, Вы писали:


ssm>Буду рад простому примеру для тех кто в башне танка с минимом объяснения.


вижу, что нас тут много в одной башне
Re: Flyweight
От: Андрей Галюзин Украина  
Дата: 13.07.04 12:20
Оценка:
s> немог бы кто-то доступно объяснить о использовании паттерна Flyweight? Перечитал вчера 3 раза
s> в "паттернах проектирования", но так до конца не понял предлагаемой реализации. Контекст
s> применения понятен, а вот реализация приведена какая-то ...
s> Буду рад простому примеру для тех кто в башне танка с минимом объяснения.

А что конкретно-то непонятно? По-моему вполне прозрачный пример...

Другое дело, что этот паттерн достаточно редко используется.

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re: Flyweight
От: _AK_ Россия  
Дата: 13.07.04 13:02
Оценка: -1
Здравствуйте, ssm, Вы писали:

ssm>Добрый день,

ssm>немог бы кто-то доступно объяснить о использовании паттерна Flyweight? Перечитал вчера 3 раза в "паттернах проектирования", но так до конца не понял предлагаемой реализации. Контекст применения понятен, а вот реализация приведена какая-то ...
ssm>Буду рад простому примеру для тех кто в башне танка с минимом объяснения.
ssm>Тройки готовы к раздаче
ssm>Спасибо

Когда тебе хочется всё "заобъектизировать", но к сожалению ты это сделать не можешь ибо, например, слишком много объектов получится. Тогда, если получится, то выделяешь некое небольшое подмножество исходных объектов, которое неким образом (с помощью каких-то дополнительных данных) можно обобщить на все объекты, и их используешь как объекты. Используется достаточно редко, я по крайней мере его не использовал ни разу. Примера — текстовый редактор из GoF.
Re[2]: Flyweight
От: ssm Россия  
Дата: 13.07.04 13:10
Оценка:
Здравствуйте, Андрей Галюзин, Вы писали:


АГ>А что конкретно-то непонятно? По-моему вполне прозрачный пример...


АГ>Другое дело, что этот паттерн достаточно редко используется.


Буду рад простому примеру с минимом объяснения
Re[2]: Flyweight
От: ssm Россия  
Дата: 13.07.04 13:34
Оценка:
Здравствуйте, _AK_, Вы писали:


_AK>Когда тебе хочется всё "заобъектизировать", но к сожалению ты это сделать не можешь ибо, например, слишком много объектов получится. Тогда, если получится, то выделяешь некое небольшое подмножество исходных объектов, которое неким образом (с помощью каких-то дополнительных данных) можно обобщить на все объекты, и их используешь как объекты. Используется достаточно редко, я по крайней мере его не использовал ни разу.


повторю еше раз : Контекст применения понятен, а вот реализация нет. Смотрел я глядел, ну хоть ты тресни... С остальными паттернами вроде все понятно, а этот
поэтому прошу простой пример для простого советского человека
Спасибо
Re[3]: Flyweight
От: _AK_ Россия  
Дата: 13.07.04 13:59
Оценка: 8 (2)
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, _AK_, Вы писали:



_AK>>Когда тебе хочется всё "заобъектизировать", но к сожалению ты это сделать не можешь ибо, например, слишком много объектов получится. Тогда, если получится, то выделяешь некое небольшое подмножество исходных объектов, которое неким образом (с помощью каких-то дополнительных данных) можно обобщить на все объекты, и их используешь как объекты. Используется достаточно редко, я по крайней мере его не использовал ни разу.


ssm>повторю еше раз : Контекст применения понятен, а вот реализация нет. Смотрел я глядел, ну хоть ты тресни... С остальными паттернами вроде все понятно, а этот

ssm>поэтому прошу простой пример для простого советского человека
ssm>Спасибо

Простой пример: пусть есть много строк, в строках много букв. Каждая буква имеете туеву хучу атрибутов (позиция, цвет, высота, ширина и т.д. и т.п.). Если каждая буква будех хранится как реальный объект (что есть правильно), то мы сдохнем (1.000.000 букв * 1.000 байт данных, ассоциированных с буквой = 1Гб). Очевидно, что эти самые данные можно хранить более экономно — только на какой-то логический блок для которого они константны. Но в то же время мы хотим иметь объект буква, которым можем манипулировать, например вызвать функцию render у неё, чтобы она отрисовалась сама. Наши 1.000.000 букв можно превратить в 255 объектов, каждый из которых умеет рисоваться. При активации объекта мы передаём внешние данные (которые у нас ассоциированы с логическим блоком) и далее оперерируем буквой как объектом.

Что сейчас непонятно?
Re[4]: Flyweight
От: korzhik Россия  
Дата: 13.07.04 14:23
Оценка: 20 (2)
Здравствуйте, _AK_, Вы писали:

AK>Что сейчас непонятно?


вот поясняющий код:
#pragma warning(disable:4786)

#include <iostream>
#include <string>
#include <map>

using namespace std;

class Character
{
protected:
    char symbol_;
    int  width_;
    int  height_;
    int  pointSize_;
public:
    virtual void Draw( int pointSize )
    {
        pointSize_ = pointSize;
        std::cout << symbol_;
    }
};

// ConcreteFlyweight

class CharacterA : public Character
{
public:
    CharacterA()
    {
        symbol_  = 'A';
        height_  = 100;
        width_   = 120;
    }
};

// ConcreteFlyweight

class CharacterB : public  Character
{
public:
    CharacterB()
    {
        symbol_  = 'B';
        height_  = 100;
        width_   = 140;
    }
};

// ... C, D, E, 

class CharacterZ : public Character
{
public:
    CharacterZ()
    {
        symbol_  = 'Z';
        height_  = 100;
        width_   = 140;
    }
};

class CharacterFactory
{
    map<char,Character*> characters_;
public:
    Character* GetCharacter( char key )
    {
        Character* character = (Character*)characters_[ key ];
        if (character == NULL)
        {
            switch (key)
            {
            case 'A': character = new CharacterA(); break;
            case 'B': character = new CharacterB(); break;
            //...
            case 'Z': character = new CharacterZ(); break;
            }
            characters_[key] = character;
        }
        return character;
    }
};

int main(int argc, char* argv[])
{
    string document = "ABZZAABA";
    
    CharacterFactory* factory = new CharacterFactory();

    int pointSize = 12;

    string::iterator last = document.end();

    for (string::iterator it = document.begin(); it != last; ++it)
    {
        Character* ch = factory->GetCharacter( *it );
        ch->Draw( pointSize );
    }

    return 0;
}


код был взят и переведён на С++ отсюда
Re[4]: Flyweight
От: ssm Россия  
Дата: 13.07.04 14:38
Оценка:
Здравствуйте, _AK_, Вы писали:


_AK>Что сейчас непонятно?


Вот это мне было, до примера korzhik, непонятно:
_AK>При активации объекта мы передаём внешние данные (которые у нас ассоциированы с логическим блоком) и далее оперерируем буквой как объектом.
Re[5]: Flyweight
От: ssm Россия  
Дата: 13.07.04 14:47
Оценка:
Здравствуйте, korzhik, Вы писали:

Отдельное спасибо за ссылку, но мне кажется с "Frequency of use" они IMHO, мягко скажем, неадэкватно оценивают ситуацию
Re[5]: Flyweight
От: korzhik Россия  
Дата: 16.07.04 21:22
Оценка:
Здравствуйте, korzhik, Вы писали:

чтобы меня не обвиняли в том что я распрастроняю код с утечками, привожу код без утечек:
#include <iostream>
#include <string>
#include <map>
#include <memory> // for auto_ptr
#include <boost/shared_ptr.hpp>

using namespace boost;
using namespace std;

class Character
{
protected:
    char symbol_;
    int  width_;
    int  height_;
    int  pointSize_;
public:
    virtual void Draw( int pointSize )
    {
        pointSize_ = pointSize;
        std::cout << symbol_;
    }
};

// ConcreteFlyweight

class CharacterA : public Character
{
public:
    CharacterA()
    {
        symbol_  = 'A';
        height_  = 100;
        width_   = 120;
    }
};

// ConcreteFlyweight

class CharacterB : public  Character
{
public:
    CharacterB()
    {
        symbol_  = 'B';
        height_  = 100;
        width_   = 140;
    }
};

// ... C, D, E, 

class CharacterZ : public Character
{
public:
    CharacterZ()
    {
        symbol_  = 'Z';
        height_  = 100;
        width_   = 140;
    }
};

typedef shared_ptr<Character> chPtr;

class CharacterFactory
{
    map<char,chPtr> characters_;
public:
    chPtr GetCharacter( char key )
    {
        chPtr character( characters_[ key ] );
        if (!character)
        {
            switch (key)
            {
            case 'A': character.reset(new CharacterA()); break;
            case 'B': character.reset(new CharacterB()); break;
            //...
            case 'Z': character.reset(new CharacterZ()); break;
            }
            characters_[key] = character;
        }
        return character;
    }
};

int main(int argc, char* argv[])
{
    string document = "ABZZAABA";
    
    auto_ptr<CharacterFactory> const factory( new CharacterFactory());

    int pointSize = 12;

    string::iterator last = document.end();

    for (string::iterator it = document.begin(); it != last; ++it)
    {
        chPtr ch = factory->GetCharacter( *it );
        ch->Draw( pointSize );
    }
}
Re[2]: Flyweight
От: Alexey Chen Чили  
Дата: 17.07.04 10:30
Оценка:
Здравствуйте, _AK_, Вы писали:
_AK> ... Используется достаточно редко, я по крайней мере его не использовал ни разу. ...
Уверен?

Допустим, у нас есть множество рендерабельных обьектов, каждый из которых связан с некоторой текстурой.
Также у нас есть фабрика текстур, параметризующая содание текстуры по имени ресурса и типу текстуры.
Можно при каждом обращении к этой фабрике создавать новую текстуру и связывать с ней рендерабельный обьект, но обычно ведь так не делают. Делают фабрику, которая хранит каталог с ссылками на уже существующие текстуры, и при запросе текстуры, если подходящая уже существует, возвращает ее прокси, увеличивая количество ссылок.

Собственно, прокси со счетчиком ссылок управяет временем жизни обьекта и к патерну приспособленца отношения не имеет
Re: Flyweight
От: Mishka Норвегия  
Дата: 19.07.04 08:38
Оценка: 3 (1)
Здравствуйте, ssm,

Flyweight использовал только однажды. Лучше всего он работает вместе с пулом. У меня формы были в web-приложении, которые приходилось создавать каждый раз, когда люди постили страницу, а они были достаточно тяжеловестны. Вот я и решил создать pool, человек обращается к форме, я беру её из пула, передаю ей контекст, в котором она должна выполняться, и вперёд.

Примерно так:
class Form
{
  void SetContext(... параметры контекста ...){}
  void Free(){... почистить всё внутреннее состояние...}
  // далее функции формы
}

// А потом где-то в управляющем сервлете или http-хандлере

Form form = pool.GetForm(... некие параметры ...); // или просто Form form = new Form();
form.SetContext(...); // установить переменные окружения (контекста)

// работаем с формой

form.Free();
pool.ReturnForm(form); // возвращаем её в pool, или ничего не делаем если создали её через new Form()
Re: Flyweight
От: Дарней Россия  
Дата: 19.07.04 09:32
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>немог бы кто-то доступно объяснить о использовании паттерна Flyweight? Перечитал вчера 3 раза в "паттернах проектирования", но так до конца не понял предлагаемой реализации. Контекст применения понятен, а вот реализация приведена какая-то ...


в качестве примера можно привести объектную модель документа в Word. Первое, что напрашивается в голову (и как оно и сделано, я подозреваю ) — это для каждого элемента (абзаца, строки, символа) создать объект, а эти объекты поместить в соотв коллекции. У каждого объекта свои свойства -> получается очень тяжеловесно, много данных дублируется. Как правило, соседние символы имеют одинаковые атрибуты (шрифт, размер шрифта, цвет и т.д. и т.п.) Поэтому лучше сделать так: текст храним просто в виде массива символов, атрибуты фрагментов помечаем тэгами. Когда юзер пытается получить символ под нумером такой-то, берем объект "символ" из пула объектов, выставляем все нужные атрибуты и отдаем юзеру. Когда он закончил с этим символом — возращаем объект в пул.

Если что-то неправильно, сильно не бейте
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[2]: Flyweight
От: Mishka Норвегия  
Дата: 19.07.04 09:34
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Если что-то неправильно, сильно не бейте


Да всё правильно, только вот интересно, почему это все приводят примеры текстового редактора
Re[3]: Flyweight
От: hrg Россия  
Дата: 19.07.04 09:37
Оценка: :)
Mishka -> "Re[2]: Flyweight" :

Д>> Если что-то неправильно, сильно не бейте


M> Да всё правильно, только вот интересно, почему это все приводят

M> примеры текстового редактора

Это все GoF!.

ЗЫ Возмем например ноты и нотный редактор

Yury Kopyl aka hrg | http://id.totem.ru | "Спам придумали боги в отместку
за наши молитвы."
Posted via RSDN NNTP Server 1.9 beta
Re[4]: Flyweight
От: Mishka Норвегия  
Дата: 19.07.04 09:40
Оценка:
Здравствуйте, hrg, Вы писали:

hrg>ЗЫ Возмем например ноты и нотный редактор


Никакой разницы.
Лучше бы из своей практики приводили примеры А то складывается ощущение, что все пишут редакторы
Re[3]: Flyweight
От: Дарней Россия  
Дата: 19.07.04 11:33
Оценка:
Здравствуйте, Mishka, Вы писали:

M>Да всё правильно, только вот интересно, почему это все приводят примеры текстового редактора


наверно, просто стереотипное мЫшление
хотя я одно время, помнится, макросы для этого самого Ворда писал. Блин, как же оно тормозит (
Мне особенно одна вешь понравилась. Оказывается, если запросить свойство, которое представляет общее число символов в доке — Ворд пересчитывает все символы по каждому запросу То есть значение не кэшируется нигде. Я еще сначала удивлялся — чего это макрос так долго работает
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re: Flyweight
От: korzhik Россия  
Дата: 29.07.04 10:24
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Добрый день,

ssm>немог бы кто-то доступно объяснить о использовании паттерна Flyweight? Перечитал вчера 3 раза в "паттернах проектирования", но так до конца не понял предлагаемой реализации. Контекст применения понятен, а вот реализация приведена какая-то ...
ssm>Буду рад простому примеру для тех кто в башне танка с минимом объяснения.
ssm>Тройки готовы к раздаче
ssm>Спасибо

нашёл интересную ссылку по сабжу.
Re[6]: Flyweight
От: kelvin  
Дата: 19.08.04 09:44
Оценка:
Здравствуйте, korzhik, Вы писали:
K>чтобы меня не обвиняли в том что я распрастроняю код с утечками, привожу код без утечек:
Ты что предлагаешь на каждую букву класс плодить?
Какой в этом тайный смысл?
... << RSDN@Home 1.1.4 @@subversion >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.