Слишком много получилось писать в комментарии, решил вынести в отдельный пост.
В приведеном случае, когда логика постоянно меняется (пример кода в моем комментарии на пост Евгения), действительно лучше всего подойдет паттерн 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.
Естественно, пример очень абстрасктный, но думаю, что основную логику рефакторинга он показывает.
Если приводить пример более приближенный к реальности, то таким образом можно связать объект и его маппер в базу данных.
Комментариев нет:
Отправить комментарий