Приспособленец (Flyweight) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Код)
(Код)
Строка 21: Строка 21:
 
=== Пример ===
 
=== Пример ===
 
В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста.
 
В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста.
=== Код ===
+
=== Код примера ===
 
<source lang="Csharp">
 
<source lang="Csharp">
 
class MainApp
 
class MainApp

Версия 09:22, 8 августа 2014

К основной странице курса

Назначение

Уменьшает количество объектов системы с многочисленными низкоуровневыми особенностями путем совместного использования подобных объектов.

Описание

В некоторых приложениях имеется множество небольших объектов, и задача экономии памяти выходит на первый план. Паттерн Flyweight предназначен для уменьшения количества объектов в системе за счет их совместного использования. Группа объектов может быть объединена в один объект если какая-то часть состояния у них совпадает. Несовпадающую же часть (так называемый внешний контекст) предлагается передавать в качестве параметра операции.

Назначение

Паттерн Flyweight можно использовать в случаях когда:

  • в приложении имеется множество почти одинаковых объектов
  • различающиеся части почти одинаковых объектов можно отделить от одинаковых и заменить эти почти одинаковые объекты одним совместно используемым объектом, передавая различающуюся часть как параметр операции

Реализация

Диаграмма классов

FlyweightCommon.png

Участники

Пример

В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста.

Код примера

class MainApp
{
    static void Main()
    {
        string Str = "AAZZBBZB";

        CharacterFactory factory = new CharacterFactory();

        Context context = new Context();
        context.AddInterval(2, 4);
        context.AddInterval(6, 7);

        foreach (char c in Str)
        {
            Character character = factory.GetCharacter(c); // получить приспособленца
            character.Draw(context);
        }
    }
}

class Pair 
{
    public int Left,Right;
    public Pair(int left, int right)
    {
        Left = left;
        Right = right;
    }
}

class Context
{
    private int pos = 1;
    private List<Pair> list = new List<Pair>(); 
    public void AddInterval(int left, int right)
    {
        list.Add(new Pair(left,right));
    }
    public void Next()
    {
        pos++;
    }
    public bool InInterval()
    {
        foreach (var p in list)
        {
            if (pos >= p.Left && pos <= p.Right)
                return true;
        }
        return false;
    }
}

class CharacterFactory
{
    private Dictionary<char, Character> characters = new Dictionary<char, Character>();

    public Character GetCharacter(char key)
    {
        Character character = null;
        if (characters.ContainsKey(key)) // если есть такой приспособленец
        {
            character = characters[key]; // то просто вернуть его
        }
        else
        {
            character = new Character(key);
            characters.Add(key, character); // иначе создать, добавить к словарю приспособленцев и вернуть
        }
        return character;
    }
}

class Character
{
    private char symbol;
    public Character(char sym)
    {
        symbol = sym;
    }
    public void Draw(Context context)
    {
        if (context.InInterval())
            Console.WriteLine("Symbol = {0} BOLD", symbol); // попавшие в один из интервалов контекста символы рисуются жирным
        else Console.WriteLine("Symbol = {0}", symbol);
        context.Next(); // меняем контекст - позицию символа
    }
}

Достоинства и недостатки

Варианты