Фабричный метод или какой-то другой шаблон? - PullRequest
2 голосов
/ 01 ноября 2010

У меня есть объект «Задача», который необходимо разрешить в зависимости от типа задания. Я бы инкапсулировал логику для конкретного типа задач в классе, но каков общепринятый способ сопоставления типа с классом, который реализует логику разрешения?

Мой первый импульс - создать Фабрику, как:

TaskResolverFactory.GetForType(TaskType) // returns IsATaskResolver, which has a Resolve method

Вероятно, внутри Фабрики, заявление Case или что-то в этом роде.

Другая мысль состоит в том, чтобы использовать что-то вроде StructureMap, но я думаю, что это избыточно для этой ситуации - вы согласны?

Какие еще методы мне не хватает, и каков общепринятый метод замены большого оператора Case / Switch?

Ответы [ 3 ]

2 голосов
/ 01 ноября 2010

Вы правы - классическая модель для этой проблемы - Factory.

Если это единственное место, где вам нужно сделать такое разрешение (и логика проста), я согласен - StructureMap - это перегиб.

1 голос
/ 01 ноября 2010

Вы могли бы рассмотреть что-то вроде этого:

public class TaskResolverAttribute : Attribute
{
    public Type ResolverType { get; private set; }

    public TaskResolverAttribute(Type resolverType)
    {
        if (!typeof(ITaskResolver).IsAssignableFrom(resolverType))
            throw new ArgumentException("resolverType must implement ITaskResolver");

        ResolverType = resolverType;
    }
}

public class MyTaskResolver : ITaskResolver
{
}

[TaskResolver(typeof(MyTaskResolver))]
public class MyTask
{
}

public static class TaskResolverFactory
{
    public static ITaskResolver GetForType(Type taskType)
    {
        var attribute =
            Attribute.GetCustomAttribute(taskType, typeof(TaskResolverAttribute)) as TaskResolverAttribute;
        if (attribute == null)
            throw new ArgumentException("Task does not have an associated TaskResolver");

        return (ITaskResolver)Activator.CreateInstance(attribute.ResolverType);
    }
}
0 голосов
/ 01 ноября 2010

Фабрика - это путь.

Что касается большого оператора switch, другие ваши варианты включают:

  • Файл конфигурации / поиска
  • База данных
  • Отражение

Я думаю, что маршрут отражения проще всего поддерживать, но сложность возникает, когда у вас еще нет типа (если предположить, что ваш "тип" - Type).

Поскольку у вас уже есть тип, все остальное очень просто:

public static Task GetByType(Type taskType)
{
    return Activator.CreateInstance(taskType) as Task;
}
...