■ Подход 1, основанный на принципе "открытия задвижки " (Litch-based approach).
Любой код, которому требуется общий ресурс, обращается к статическому свойству класса GraphicsGlobals для получения его значения. Если ресурс уже загружен, он возвращается запросившему его объекту. Если ресурс еще не был загружен, то он создается, кэшируется и после этого возвращается пользователю. Такой подход обладает двумя преимуществами: 1) запрашивающий объект не должен заботиться ни о каком инициализирующем коде; в результате запроса всегда будет возвращен действительный ресурс, и 2) управляемый ресурс может быть освобожден, если приложение считает, что в течение некоторого времени в нем не будет надобности; при необходимости он будет заново создан в результате следующего запроса. Единственным недостатком такого подхода являются незначительные дополнительные накладные расходы, связанные с необходимостью вызова функции для доступа к свойству всякий раз, когда требуется ресурс; обычно этими накладными расходами можно пренебречь. ■ Подход 2, основанный на групповой обработке ресурсов (batch-based approach).
Если некоторые ресурсы используются одинаковым образом и имеют сравнимые времена существования, то они могут быть инициализированы сразу все вместе. Код, в котором должны будут использоваться эти глобальные ресурсы, может непосредственно получить доступ к переменным, но предварительно он должен удостовериться в том, что они уже были инициализированы. Когда приложение перейдет в состояние, в котором эти ресурсы в течение некоторого времени использоваться не будут, эти ресурсы должны быть освобождены, и для них должен быть вызван метод Dispose. ■ Подход 3, основанный на использовании коллекций (collection-based approach).
Если некоторые ресурсы всегда используются в виде группы, как, например, в случае битовых изображений, образующих анимационную последовательность, то имеет смысл загружать их вместе и возвращать в виде массива или коллекции ресурсов. Если загрузка ресурсов обходится слишком дорого или требует использования значительных объемов памяти, то может оказаться целесообразным хранить их экземпляры, кэшированные централизованным образом, чтобы исключить повторное создание одних и тех же ресурсов. Как и в рассмотренном выше случае, когда необходимость в этих ресурсах отпадает, их необходимо освобождать и вызывать для них метод Dispose, следуя предварительно намеченной стратегииЛистинг 11.11. Три полезных способа кэширования графических ресурсов
using System;
using System.Drawing;
internal class GraphicsGlobals {
//==========================================================================
//Подход 1: Создать ресурс по требованию
// и кэшировать его для последующего использования.
//
//Внешний код получает доступ к общедоступным свойствам для их просмотра, но
//сами переменные остаются внутренними переменными класса
//==========================================================================
private static Pen s_bluePen;
public static Pen globalBluePen {
get {
//Если перо еще не было создано
if (s_bluePen == null) {
s_bluePen =new System.Drawing.Pen(System.Drawing.Color.Blue);
}
return s bluePen;
}
} //Конец свойства
//=========================================================
//Подход 2:
//Загрузить глобально и кэшировать все
//используемые объекты Pen, ImageAttribute, Font и Brush.
//
//Внешний код получает доступ ко всем общедоступным членам,
//так что никакие функции доступа не нужны.
//=========================================================
public static Pen g_blackPen;
public static Pen g_whitePen;
public static System.Drawing.Imaging.ImageAttributes g_ImageAttribute;