Приспособленец (Flyweight) — различия между версиями
Admin (обсуждение | вклад) (→Код) |
Admin (обсуждение | вклад) (→Код) |
||
Строка 21: | Строка 21: | ||
=== Пример === | === Пример === | ||
В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста. | В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста. | ||
− | === Код === | + | === Код примера === |
<source lang="Csharp"> | <source lang="Csharp"> | ||
class MainApp | class MainApp |
Версия 09:22, 8 августа 2014
Назначение
Уменьшает количество объектов системы с многочисленными низкоуровневыми особенностями путем совместного использования подобных объектов.
Описание
В некоторых приложениях имеется множество небольших объектов, и задача экономии памяти выходит на первый план. Паттерн Flyweight предназначен для уменьшения количества объектов в системе за счет их совместного использования. Группа объектов может быть объединена в один объект если какая-то часть состояния у них совпадает. Несовпадающую же часть (так называемый внешний контекст) предлагается передавать в качестве параметра операции.
Назначение
Паттерн Flyweight можно использовать в случаях когда:
- в приложении имеется множество почти одинаковых объектов
- различающиеся части почти одинаковых объектов можно отделить от одинаковых и заменить эти почти одинаковые объекты одним совместно используемым объектом, передавая различающуюся часть как параметр операции
Реализация
Диаграмма классов
Участники
Пример
В графическом редакторе не надо хранить каждый символ в виде объекта. Достаточно хранить по одному объекту для каждого из используемых символов кодовой таблицы и в метод рисования передавать контекст рисования (например, строку-столбец). Таким образом, у каждого объекта есть внутреннее состояние (символ, который он представляет) и внешнее (строка-столбец), которое не хранится вместе с объектом, а передается ему как параметр в качестве внешнего контекста.
Код примера
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(); // меняем контекст - позицию символа
}
}