24 октября 2008 г.

Использование паттернов Strategy и Registry

Слишком много получилось писать в комментарии, решил вынести в отдельный пост.

В приведеном случае, когда логика постоянно меняется (пример кода в моем комментарии на пост Евгения), действительно лучше всего подойдет паттерн 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.

Естественно, пример очень абстрасктный, но думаю, что основную логику рефакторинга он показывает.

Если приводить пример более приближенный к реальности, то таким образом можно связать объект и его маппер в базу данных.

Комментариев нет:

Отправить комментарий