2015-07-30 3 views
0

У меня есть C# application, который хранит данные в NoSQL database. Приложение имеет класс репозитория, который использует серию объектов для перевода данных из формы NoSQL в те, что используются моделями C#, и наоборот (по существу форма ORM). Объекты реализуют интерфейс converter, и каждый объект работает на одном конкретном data type (string, bool, etc). Внутри они используют отражение для выполнения преобразования. Экземпляры этих объектов создаются методом, который возвращает объект для данного типа. В настоящее время логика выглядит примерно следующее:Избегание нескольких операторов if на фабричном методе C#

if(type == typeof(string) 
    return new StringConverter(...); 

if(type == typeof(int) || type == typeof(uint)) 
    return new IntegerConverter(...); 

... // and so on 

Однако все эти if заявления беспокоить меня. Я знаю, что могу сделать что-то вроде создания словаря для сопоставления типов методам создания, но я не уверен, приведет ли это к более легко читаемому, легкому обновлению/расширению кода (?). Учитывая необходимость создания абстракций типа, что является лучшим способом сделать это? Любые предложения приветствуются. Огромное спасибо заранее.

+0

У IntegerConverter и StringConverter есть базовый тип? Если это так, вы можете использовать это решение - http://stackoverflow.com/a/5847468/442444 – CarbineCoder

ответ

1

В идеале вложенные if-statements - это то, чего вы хотите избежать. Я цитирую полный код Кодекса Microsoft. Идея заключается в том, что вы вставляете до 3 уровней, внимание разработчика, поддерживающего код или ваш, поскольку разработчик резко уменьшается. В вашем случае, если ваша логика должна быть жестко запрограммирована, нет никакой возможности иметь последовательность if-утверждений. Однако разумный способ обойти это должен был бы следовать шаблону проектирования завода (банды четырех)

+0

Спасибо за ваши комментарии, очень ценится. Я уже использую фабрику для выполнения фактического создания, поэтому могу просто оставить вещи такими, какие они есть. – fhevol

1

Вы должны экспортировать свой код if в заводской класс.

Как вы можете видеть here, завод представляет собой шаблон GoF, который производит различные виды объектов.

В классе фабрики, это количество случаев int в порядке.

Вы должны только избежать вложенных если заявления, они делают ваш код нечитаемым

+0

Большое спасибо за ваши комментарии, это здорово, как люди готовы помочь здесь. Я уже использую фабрику для создания реальных объектов. Я пропустил эту деталь для краткости в моем первоначальном запросе. – fhevol

1

С точки зрения читаемости, следует отдавать предпочтение

switch(type.FullName){ 
    case(typeof(int).FullName) => //your logic 
    ... 
} 

Переключатель регистра-заявление является способ более удобным для чтения кода, чем If -Else и может быть быстрее. HERE вы можете подробнее узнать об этом:

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

Если коммутатор содержит более пяти элементов, он реализуется с помощью таблицы поиска или хеш-листа. Это означает, что все элементы получают одинаковое время доступа по сравнению со списком if: s, где последний элемент принимает много больше времени для достижения, поскольку он должен оценивать каждое предыдущее состояние .

И, как все уже сказали, передайте ваш switch-case в заводской класс.

+0

Спасибо за ваши комментарии, я очень ценю ваш вклад. Как уже отмечалось выше, я уже использую фабрику для выполнения фактического создания. Я посмотрю на инструкцию switch, однако некоторые из них используют логику типа type.IsEnum, поэтому это может быть не прямолинейно. – fhevol

0

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

var converterStrategies = new Dictionary<Object, IConverter>(); 
converterStrategies.Add(typeOf(string), new StringConverter(...)); 

Затем используйте TryGetValue при передаче в вашем ссылочном типе.

Возможно, вы считаете, что этот словарь является частным членом класса и заселен им при инициализации содержащего класс.

Gary McLean Hall демонстрирует этот шаблон в своей книге Adaptive Code через C#, он очень помог мне в подобных ситуациях!