Использование словарей Action вместо операторов switch - PullRequest
23 голосов
/ 24 августа 2011

Я просто просматриваю часть своего старого кода (у меня есть свободное время), и я заметил довольно длинное выражение switch. В связи с получением новых знаний, я с тех пор изменил их в следующей форме:

private Dictionary<string, Action> createView
    {
        get
        {
            return new Dictionary<string, Action>()
            {
                {"Standard", CreateStudySummaryView},
                {"By Group", CreateStudySummaryByGroupView},
                {"By Group/Time", CreateViewGroupByHour}
            };
        }
    }

Считаете ли вы эту хорошую практику, или это просто случай излишнего и ненужного? Я стремлюсь к тому, чтобы новые методы, которые я изучаю, были не просто умны ради них, а чтобы они действительно приносили пользу коду.

Спасибо.

Ответы [ 4 ]

18 голосов
/ 24 августа 2011

Длинные операторы переключения являются классическим неприятным запахом и всегда являются целью для рефакторинга.

"Стандартный" шаг, который необходимо выполнить, это Заменить условное на полиморфизм .Это был один из шагов, перечисленных в книге Мартина Фаулера Refactoring (опубликованной 11 лет назад в 1999 году).

Теперь, когда так легко обрабатывать функции, как объекты (например, с помощью Action), это можетбыть таким же хорошим решением.

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

9 голосов
/ 24 августа 2011

В зависимости от вашего приложения вы можете избежать создания нового объекта словаря, но объявлять его как член класса, инициализировать при первом доступе и всегда возвращать один и тот же экземпляр.Но сложно сказать, будет ли это соответствовать вашим потребностям.Таким образом, я имею в виду

public class MyClass 
{
   Dictionary<string, Action> dict = null; 

    private Dictionary<string, Action> createView
    {
        get
        {
            if(dict  == null) 
            {
              dict  = new Dictionary<string, Action>()
              {
                {"Standard", CreateStudySummaryView},
                {"By Group", CreateStudySummaryByGroupView},
                {"By Group/Time", CreateViewGroupByHour}
              };
            }

            return dict;
        }
    }

}

РЕДАКТИРОВАТЬ

С концептуальной точки зрения, я заменил long swicth/case на словарь TryGetValueдовольно хорошее решение.

Надеюсь, это поможет ...

5 голосов
/ 24 августа 2011

Этот подход превосходен.

Я использую это больше, чем просто Action. Это также довольно эффективно для фильтров и селекторов. Что-то вроде:

var filters = new Dictionary<string, Func<MyEntity, bool>>()
{
    // ...
};

var query = entities.Where(filters["X"]);
2 голосов
/ 24 августа 2011

Если код, когда-то написанный, в значительной степени статичен и не подвержен слишком большим изменениям, то я бы остановился на switch. Ваш словарный подход здесь, по крайней мере на первый взгляд, прекрасно подходит для того, чтобы быть более динамичным - хотя это больше основано на требованиях.

Что касается замены коммутаторов везде кодом, использующим этот подход, я бы лично не делал этого в большинстве случаев. Мое честное мнение таково, что это было бы просто умно ради этого, но это все еще легко поддерживать. Личный вкус, а не лучшая практика, на мой взгляд, является самым большим фактором.

С другой стороны, как уже говорили другие, это может быть реальным решением для длинных операторов switch. С другой стороны, что-то вроде паттерна стратегии также будет хорошим способом поддержки изменений в поведении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...