Слишком много получилось писать в комментарии, решил вынести в отдельный пост.
В приведеном случае, когда логика постоянно меняется (пример кода в моем комментарии на пост Евгения), действительно лучше всего подойдет паттерн Visitor.
Но для такого простого варианта, когда классу ClassA соответствует определеная функция, лучше все-таки использовать Стратегию.
Предлагаю модификацию реализации стратегии Евгения.
Лучше вынести информацию о сопоставлении типа класса к IHandler в отдельную сущность. Т.е. создать статический Регистр с тем же словарем.
public class BaseClass
{
}
public class ClassA : BaseClass
{
}
public interface IHandler<T> where T : BaseClass
{
void DoFor(T obj);
}
public class MyClass
{
public void DoSomethingWith<T>(T obj) where T : BaseClass
{
// какая-то логика
HanlderRegistry.Get<T>().DoFor(obj);
}
}
public static class HanlderRegistry
{
private static readonly Dictionary<Type, Type> _handlers = InitHanlders();
private static Dictionary<Type, Type> InitHanlders()
{
return new Dictionary<Type, Type>
{
{typeof (ClassA), typeof(HanlderForClassA)}
};
}
public static IHandler<T> Get<T>() where T : BaseClass
{
Type hanlderType = _handlers[typeof (T)];
return Activator.CreateInstance(hanlderType) as IHandler<T>;
}
}
internal class HanlderForClassA : IHandler<ClassA>
{
public void DoFor(ClassA obj)
{
// логика работы с классом ClassA
}
}
Здесь, HanlderRegistry - это единственное место, в котором происходит сопоставление обработчиков и подклассов BaseClass.
Естественно, пример очень абстрасктный, но думаю, что основную логику рефакторинга он показывает.
Если приводить пример более приближенный к реальности, то таким образом можно связать объект и его маппер в базу данных.
Комментариев нет:
Отправить комментарий