Привет всем!
Пусть имеется множество строковых ключей. На нем вводится отношение эквивалетности, порожденное функцией ConstraintExpression.Canonize.
Этих ключей извне приходит большое количество, и по каждому нужно взять объект чтобы выполнить на нем относительно тяжеловесную обработку.
Для ключей в пределах класса эквивалентности вся обработка одинаковая. Однако инициализация перед ее началом занимает много ресурсов.
Инициализация частично отложенная, так что создать новый объект хоть и дороже, чем не создавать его, но гораздо дешевле, чем использовать
новый объект для вызова DoHardWork вместо ранее созданного эквивалентного.
Поэтому хочется не создавать лишних объектов, а использовать уже существующие по возможности. Например так
public class Factory
{
public Constraint Create( string expression )
{
lock ( lock_ )
{
Constraint candidate;
if ( map_.TryGetValue( expression, out candidate ) )
{
return candidate;
}
candidate = new Constraint( expression );
var canonic = candidate.Canonic;
Constraint result;
if ( !map_.TryGetValue( canonic, out result ) )
{
result = candidate;
map_[canonic] = result;
}
map_[expression] = result;
return result;
}
}
private readonly IDictionary<string, Constraint> map_ = new Dictionary<string, Constraint>( StringComparer.InvariantCultureIgnoreCase );
private readonly object lock_ = new object();
}
public class Constraint
{
public Constraint( string expression )
{
Expression = expression;
Canonic = Canonize( expression );
}
public string Expression { get; private set; }
public string Canonic { get; private set; }
public string DoHardWork() {}
private string Canonize( string key ) { return key.ToLower(); } // Только для примера
}
А вопрос в том, можно ли переписать фабрику без блокировок?
Спасибо.