Приспособленец (Flyweight)

Шаблон Приспособленец применяется для уменьшения затрат при работе с большим количеством объектов. Приспособленец – это разделяемый объект, который можно использовать одновременно в нескольких контекстах. Чтобы это стало возможным, у объекта выделяют внутреннее и внешнее состояния. Внутреннее состояние (intrinsic state) хранится в приспособленце и состоит из информации, не зависящей от контекста. Именно поэтому оно может разделяться. Внешнее состояние (extrinsic state) зависит от контекста и изменяется вместе с ним, поэтому не подлежит разделению. Клиент отвечает за передачу внешнего состояния приспособленцу, когда в этом возникает необходимость.

Опишем компоненты шаблона Приспособленец (рис. 6). Класс Flyweight является базовым классом для любого приспособленца и отражает возможность передачи в приспособленец внешнего состояния. От этого класса наследуются конкретные классы приспособленцев – как с внутренним состоянием (ConcreteFlyweight), так и без него (UnsharedFlyweight). Класс FlyweightFactory – это фабрика приспособленцев, которая содержит метод для получения необходимого приспособленца по ключу.

Рис. 6. Диаграмма шаблона Приспособленец.

Приведём пример использования шаблона Приспособленец. Пусть необходимо работать с текстом, состоящим из букв латинского алфавита и пробельных символов. Абстрактный класс Character описывает один символ текста, занимающий определённую позицию (она играет роль внешнего состояния).

public abstract class Character

{

public abstract void Display(int position);

}

У класса Character есть два наследника: класс Latin хранит символ латинского алфавита (это его разделяемое внутреннее состояние), класс Whitespace представляет пробел (и не имеет разделяемого состояния).

public class Latin: Character

{

public char Symbol { get; set; }

public override void Display(int position)

{

Console.WriteLine("{0} (position {1})", Symbol, position);

}

}

public class Whitespace: Character

{

public override void Display(int position)

{

Console.WriteLine("_ (position {0})", position);

}

}

Для эффективного хранения символов используем класс CharacterFactory.

public class CharacterFactory

{

private Dictionary<char, Character> _chars =

new Dictionary<char, Character>();

public Character GetCharacter(char key)

{

if (!_chars.ContainsKey(key))

{

if (key == ' ')

{

_chars.Add(key, new Whitespace());

}

else

{

_chars.Add(key, new Latin {Symbol = key});

}

}

return _chars[key];

}

}

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

var document = "AA BB AB";

var chars = document.ToCharArray();

var f = new CharacterFactory();

// position - это внешнее состояние

var position = 0;

// используем для каждого символа объект-приспособленец

foreach (var c in chars)

{

var character = f.GetCharacter(c);

character.Display(position++);

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: