2010-11-01 4 views
2

У меня есть объект задачи, который должен быть разрешен в зависимости от типа задачи. Я бы инкапсулировал логику для конкретного типа задачи в классе, но каков общепринятый способ сопоставления типа с классом, реализующим логику разрешения?Метод фабрики или какой-либо другой шаблон?

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

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

Вероятно внутри завода, заявление Case или что-то.

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

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

ответ

1

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

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

Вау - я не кодировал Атрибуты, это выглядит невероятно просто. Спасибо за это! – grefly

+0

@grefly, он хорошо подходит для подобных случаев. MS использует тот же шаблон для сопоставления классов TypeConverter: http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverterattribute.aspx –

+0

Я думаю, это именно то, что я искал, не зная, что я искал. Спасибо, повторно назначил вам ответ, извинившись перед @Oded. – grefly

2

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

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

+0

К сожалению, чтобы переключиться на вас - Атрибуты ответ кажется идеальным. – grefly

+0

@grefly - проблем нет. Вы должны пойти с лучшим ответом, как видите. Однако, возможно, в будущем, подождите день или два, прежде чем принимать ответ, чтобы узнать, что происходит. – Oded

+0

Да, сделаю - прыгнул пистолет. – grefly

0

Завод - это путь.

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

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

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

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

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

Спасибо за то, что вы немного подробнее познакомились. Извините, я не могу отметить оба как Ответ. – grefly

+0

Моя реализация (который я думаю, поможет описать этот вопрос) будет выглядеть так: GetByType (TaskType) если (TaskType Is AddUserTask) возвращение AddUserTaskResolution если (TaskType ли RemoveUserTask) возвращение RemoveUserTaskResolution и т.д. – grefly

Смежные вопросы