Статьи

Обучающий шаблон Flyweight с примерами Java

Сегодняшний шаблон — это шаблон Flyweight, используемый для эффективного распределения большого количества объектов.

Мухи в реальном мире 

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

Refcard Designs Patterns
Для лучшего обзора самых популярных шаблонов дизайна, лучше всего начать с Refcard Designs Patterns от DZone

Образец мухи

Flyweight известен как структурный шаблон, так как он используется для формирования больших структур объектов на многих различных объектах. Определение Flyweight, представленное в оригинальной книге «Банды четырех» на DesignPatterns, гласит: 

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

Рассматривая этот шаблон, вам нужно подумать о внутренних и внешних данных. Внутренние данные — это данные, которые делают этот экземпляр объекта уникальным. Между тем, внешние данные — это информация, которую можно передать через аргументы. Таким образом, если вы можете сделать некоторые данные внешними для случаев, когда у вас есть большое количество объектов, шаблон Flyweight может быть именно тем, что вы ищете. 

Интерфейс Flyweight объявляет методы, которые экземпляры flyweight могут получать и использовать внешние данные. FlyweightFactory отвечает за создание и управление балансиры, гарантируя , что они разделяют правильно. Если требуемый Flyweight еще не создан, он создаст и вернет его. В противном случае он вернет один из текущего пула маховиков. 

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

Буду ли я использовать этот шаблон?

Этот шаблон следует использовать, когда: 

  • Многие подобные объекты используются и стоимость хранения высока
  • Большинство данных о состоянии каждого объекта могут быть сделаны внешними
  • Несколько общих объектов легко заменили бы многие общие объекты
  • Личность каждого объекта не имеет значения

Типичный случай для этого шаблона — с системными ресурсами, как упомянуто в нашем примере из реального мира. Значки или папки являются хорошими кандидатами для использования этого шаблона. 

Так как это работает в Java?

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

Сначала мы создадим интерфейс для наших маховиков. Метод draw предоставляет внешние данные о том, где рисовать линию

//Flyweightpublic interface LineFlyweight{public Color getColor();public void draw(Point location);}

Линия будет реализовывать этот интерфейс: 

//ConcreteFlyweightpublic class Line implements LineFlyweight{private Color color; public Line(Color c){color = c;}public Color getColor(){return color;}public void draw(Point location){//draw the character on screen}}

Наша фабрика будет управлять созданием линейных объектов: 

//Flyweight factorypublic class LineFlyweightFactory{private List<LineFlyweight> pool; public LineFlyweightFactory(){pool = new ArrayList<LineFlyweight>();}public LineFlyweight getLine(Color c){//check if we've already created a line with this color for(LineFlyweight line: pool){if(line.getColor().equals(c)){return line;}}//if not, create one and save it to the poolLineFlyweight line = new Line(c);pool.add(line);return line;}}

Когда клиент хочет создать строку, он может использовать фабрику следующим образом: 

LineFlyweightFactory factory = new LineFlyweightFactory(); ....LineFlyweight line = factory.getLine(Color.RED); LineFlyweight line2 = factory.getLine(Color.RED); //can use the lines independentlyline.draw(new Point(100, 100));line2.draw(new Point(200, 100));

Остерегайтесь недостатков

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

Следующий

На следующей неделе мы рассмотрим модель моста.

Наслаждайтесь всей серией «Design Patterns Uncovered»:

Образцы творчества

Структурные паттерны

Поведенческие образцы