Паттерны State и FlyWeight

Кто-нибудь может поделиться примером использования шаблона состояния с шаблон легковеса (шаблон легковеса предназначен для создания объектов состояния для экономии памяти)?

ОБНОВЛЕНИЕ: Как использовать комбинацию шаблонов состояния и fw?


person drifter    schedule 04.02.2012    source источник
comment
у тебя два вопроса. по одному на каждый шаблон. Переместите один из них в отдельный вопрос   -  person jgauffin    schedule 04.02.2012
comment
На каждой из этих вики-страниц есть пример. В Яве.   -  person Brian Roach    schedule 04.02.2012
comment
@jgauffin Насколько я вижу, он задал один вопрос, как использовать комбинацию шаблонов состояния и fw.   -  person DPM    schedule 04.02.2012
comment
да. Истинный. я неправильно понял вопрос   -  person jgauffin    schedule 04.02.2012


Ответы (2)


Autoboxing использует шаблон приспособленца, чтобы свести к минимуму создание объектов (для небольших значений Integer).

например для Boolean и Byte кэшируются все возможные значения.

Java использует состояния для многих компонентов, однако конечный автомат также включает функции, переключаемые состоянием.

Вот пример, который я написал, используя enum http://vanillajava.blogspot.com/2011/06/java-secret-using-enum-as-state-machine.html

person Peter Lawrey    schedule 04.02.2012
comment
Автобоксинг — это пример шаблона наилегчайшего веса [так в оригинале]... Разве это не немного странная формулировка и еще более странный пример!? Можно сказать, что кэширование/повторное использование для небольших значений на самом деле является деталью по сравнению с тем, что делает автоупаковка. Кроме того, целью шаблона легковеса является экономия памяти, а автоупаковка — это последнее средство для экономии памяти. Я даже не буду упоминать трату памяти при хранении целочисленных {ключей, значений} в карте Java по умолчанию по сравнению с эквивалентом в Trove TIntIntHashMap. Так что я думаю, что говорить, что автобокс является примером паттерна наилегчайшего веса, может быть немного странно. - person TacticalCoder; 04.02.2012
comment
Приспособленцы обычно являются просто деталями по сравнению с тем, что на самом деле делает функция. Это потому, что они разработаны, чтобы быть в значительной степени прозрачными. то есть сделано исключительно из соображений производительности. - person Peter Lawrey; 04.02.2012
comment
Разница между использованием HashMap и TIntIntHashMap заключается в способе организации записей. Если целые числа кэшируются, размер в противном случае будет таким же. например если вы сравните TIntArrayList и ArrayList<Integer> для кешей. - person Peter Lawrey; 04.02.2012
comment
+1 Мне намного больше нравится ваша перефразированная версия: исходная формулировка была немного странной, что я и хотел сказать; ) Да, на 32-битных виртуальных машинах, если бы вы поместили только записи между -128 и 127, размер был бы таким же, но я бы сказал, что это был бы совершенно особый случай. На 64-битных виртуальных машинах, даже на последних Sun, использующих сжатые указатели по умолчанию, он все равно будет немного больше (если я не ошибаюсь). Но в любом случае, это не моя точка зрения: я просто сказал, что Автобоксинг — это пример шаблона наилегчайшего веса [так в оригинале] прозвучало для меня немного странно, мне больше нравится ваше новое редактирование, +1 ! :) - person TacticalCoder; 04.02.2012
comment
64-разрядная JVM Sun/Oracle 6+ по умолчанию использует сжатые ссылки (если размер кучи не превышает 32 ГБ). - person Peter Lawrey; 04.02.2012
comment
Sun/Oracle 64-bit JVM 6+ по умолчанию использует сжатые ссылки... Только начиная с 6u23+ (если мне не изменяет память и если я не ошибаюсь ; ), именно поэтому я написал < i>даже последние Sun используют сжатые указатели по умолчанию ; ) - person TacticalCoder; 04.02.2012

Обычно я использую шаблон состояния, чтобы избежать условных операторов.

вместо использования:

switch (state)
{
    case ParserState.BeforeMethod:
        //do some processing
        break;
    case ParserState.InMethod:
        //do some processing
        break;
}

Я могу просто написать:

currentState = currentState.process(context);

Пример класса может выглядеть так

public class SomeClass : ParserState
{
    public ParserState process(IParserContext context)
    {
       //do some proceccing

       if (m_completed)
           return new SomeOtherState();

       return this;
    }

}

т. е. логика перемещается в небольшие классы, которые используются для обработки определенного состояния. Таким образом, вы получаете две вещи:

  • Небольшие классы с четкими обязанностями
  • Меньше условных операторов = более читаемый код.
person jgauffin    schedule 04.02.2012