В случае, если ваши правила могут стать более сложными, чем простое сравнение свойств, вы можете оставить опцию, чтобы сделать немного больше, например ::10000
interface IFactoryRule
{
bool CanInstantiate(PropertySet propSet);
}
Тогда простая реализация будет выглядеть так:
// compares property set to given parameters
public SimpleRule : IFactoryRule
{
private readonly int a,b,c;
public SimpleRule(a,b,c) { ... }
public bool CanInstantiate(PropertySet propSet)
{
return
propSet.a == a &&
propSet.b == b &&
propSet.c == c;
}
}
Но вы также можете создавать сложные пользовательские правила любого вида:
// compares property set using a delegate
public ComplexRule : IFactoryRule
{
private readonly Func<PropertySet, bool> _func;
public ComplexRule(func) { ... }
public bool CanInstantiate(PropertySet propSet)
{
return _func(propSet);
}
}
добавьте всевозможные решения на ваш завод:
public class MyClassFactory
{
private static List<Tuple<IFactoryRule, Func<IMyClass>>> _rules = new List();
static MyClassFactory()
{
// rules are evaluated in this same order
_rules.Add(new SimpleRule(1,2,3), () => new Simple());
_rules.Add(new ComplexRule(p => p.a + p.b == p.c), () => new Complex());
}
public static IMyClass Create(PropertySet pset)
{
if (pset == null)
throw new ArgumentNullException("pset");
// try to find a match
Tuple<IFactoryRule, Func<IMyClass>> rule =
_rules.FirstOrDefault(r => r.First.CanInstantiate(pset));
if (rule == null)
throw new ArgumentException(
"Unsupported property set: " + pset.ToString());
// invoke constructor delegate
return rule.Second();
}
}
[Редактировать: добавлен метод MyClassFactory.Create
]
Как вы можете видеть, в этом решении нет отображения хеш-правил, поэтому список правил оценивается один за другим в методе Create
(FirstOrDefault
будет повторять список до тех пор, пока не будет найдено первое совпадение).
Если у вас много правил (скажем, больше 20) и вы создаете миллион объектов, вы заметите разницу в скорости по сравнению с решением HashSet
(но эти два подхода на самом деле нельзя сравнить поскольку hashset может только сравнивать равенство).
Кроме того, использование похоже на Решение Эндрю :
IMyClass instance = MyClassFactory.Create(propSet);