Понимание рисунка мухи

Цель:

Цель этого шаблона - использовать общий доступ для поддержки большого количества объектов, которые имеют часть своего внутреннего состояния, в котором другая часть состояния может меняться.

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

В чем разница между совместным использованием внутреннего состояния большого количества объектов с использованием шаблона flyweight и использованием статических полей?

Является ли пул объектов, которые мухи обеспечивают через его Factory, что такое мухи?

Ответ 1

Используя статические поля, может быть только один экземпляр объекта, который будет использоваться в любой момент времени. Используя шаблон мухи, вы можете использовать любое количество разных экземпляров одновременно (каждый из которых используется несколько раз). Канонический пример шаблона мухи для текстового редактора, где вам нужен экземпляр объекта для каждого символа в документе. Вместо того, чтобы иметь один объект в памяти для каждого символа в документе размером 10 000 слов, тогда вам нужно только 26 объектов (при условии, что документ использует только строчные буквы), один для буквы "a" , один для буквы "b" и т.д.., и они повторно используются, временно, снова и снова по всему документу, каждый раз, когда вам нужно выполнить какую-либо функцию или действие, требующее объект 'a'.

EDIT: ответить на вопрос с первого комментария ниже:
Итак, поскольку вам нужны 26 разных объектов, создание класса Letter, статичного или синглтона, не сработает. Если он был статичным, вы не можете создавать какие-либо экземпляры, и поэтому любые статические значения должны были бы соответствовать каждому месту в коде, в котором вы его использовали. Если бы это был синглтон, тогда, конечно, у вас есть только один объект. Каждое свойство должно быть регулируемым (и настраиваться) каждый раз, когда вы его использовали. Чтобы использовать этот шаблон для букв в алфавите, у вас должно быть 26 разных классов, по одному для каждой буквы...

Кроме того, "часть класса, которая может меняться", действительно означает, что некоторые поля представляют состояние, которое отличается для каждого экземпляра класса. Принимая во внимание, что общая часть означает, что значения этих общих полей являются общими для всех видов использования объекта, соответствующих этим значениям состояния (все, например, "a" ), а не для каждого экземпляра класса.

Опять же, используя текстовый редактор в качестве примера. Каждое место в вашем коде, которое вам нужно обработать с символом "a" , вы должны сначала перейти к структуре данных, в которой хранятся ваши 26 экземпляров объектов символа, и получить экземпляр "a" , Сначала вы измените/измените изменяющиеся свойства (свойства не привязаны к нему как "a" , но, возможно, к его размеру, положению, цвету и т.д.), Чтобы соответствовать потребностям для этого конкретного символа "a" в документ.
Затем вы будете использовать объект для выполнения того, что вам нужно сделать с ним, а затем вернуть его в структуру хранилища для повторного использования в следующий раз, когда вашему коду понадобится "a" .

Ответ 2

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

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

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

Источник Статика С# в MSDN

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

Итак, если ваш язык выбора - С#, вам может быть рекомендовано рассмотреть шаблон Flyweight против присущих ему свойств, которые уже существуют на этом языке.

Ответ 3

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

Если вы можете использовать статику, это здорово. В противном случае вы можете сделать что-то похожее на то, что вы затронули... ваш factory, который создает объекты с мухой, может назначать/ссылаться на соответствующий общий объект.

Ответ 4

Вот пример, он печатает всех солдат и их украшения.

Поскольку не все солдаты оформлены, мы используем шаблон дизайна flyweight.

public class Soldiers
{
  private string[] _soldiers;
  private Dictionary<int, Decoration> _decorations = new Dictionary<int, Decoration>();

  public Soldiers(string[] soldier)
  {
    this._soldiers = soldier;
  }

  public Decoration this[int index]
  {
    get
    {
      Decoration decoration = new Decoration();
      this._decorations.Add(index, decoration);
      return this._decorations[index];
    }
  }

  public override string ToString()
  {
    var soldierList = new List<string>();
    for (var i = 0; i < this._soldiers.Length; i++)
    {
      string soldier = this._soldiers[i];
      if (this._decorations.ContainsKey(i))
        soldier = soldier + ", Decoration: " + this._decorations.ElementAt(i).ToString();
      soldierList.Add(soldier);
    }
    return string.Join("; ", soldierList);
  }

  public class Decoration
  {
    public bool Bronze;
    public bool Silver;
    public bool Gold;

    public override string ToString()
    {
      return (this.Bronze ? "Bronze," : "") + (this.Silver ? "Silver," : "") + (this.Gold ? "Gold" : "")
    }
  }
}

Использование:

Soldiers soldiers = new Soldiers(new string[] { "SoldierA" , "SoldierB" , "SoldierC" });

soldiers[0].Gold = true;
soldiers[0].Silver = true;
soldiers[2].Bronze = true;
Console.Write(soldiers.ToString()) // "SoldierA, Decoration: Silver,Gold; SoldierB; SoldierC, Decoration: Bronze";