2017-01-16 3 views
3

СценарийЕсть ли какая-либо польза от использования полиморфизма над Enum в этом сценарии?

Я создаю динамический конструктор запросов послать к другому компоненту (отчет застройщика).

В некоторых частях запроса есть заполнители. Например:

SELECT DISTINCT ID, NAME AS VALUE FROM EVENTS 
WHERE {{ESTABLISHMENTFILTER.ID}} IS NULL OR ESTABLISHMENT_ID = {{ESTABLISHMENTFILTER.ID}} 

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

Мой первый подход заключается в создании Enum:

public enum FilterType 
{ 
    Integer, 
    String 
} 

и использовать его, как это (в бизнес-уровне, например)

switch (filter.Type) 
{ 
    case FilterType.Integer: 
     //Do replace logic for an integer 
     break; 
    case FilterType.String: 
     //Do replace logic for a string 
     break; 
    default: 
     break; 
} 

Я также применяя SOLID принципы моего кода, и я понял, что это может сломать OCP. Поэтому я переработан использовать базовый класс

public abstract class FilterType 
{ 
    public abstract string Replace(string baseString, string oldValue, string newValue); 
} 

и каждый тип имеет свою собственную реализацию:

public class FilterTypeInteger : FilterType 
{ 
    public override string Replace(string baseString,string oldValue, string newValue) 
    { 
     //Do logic to replace for an Integer type 
    } 
} 

Проблема

твердый раствор работал на моих тестах, но в производственном коде в базе данных есть столбец int, чтобы определить тип. Таким образом, я в основном передаю логику «switch-case» на datalayer, который должен будет проверить этот столбец, чтобы создать экземпляр правильного FilterType (код ниже - это псевдокод, потому что я еще не реализовал его):

if (dataReader["FILTERTYPE"] == 1) 
     filter.Type = new FilterTypeInteger(); 
    else if (dataReader["FILTERTYPE"] == 2) 
     filter.Type = new FilterTypeString(); 

Вопросы,

1) способ реализации логики 'если-то' выше нарушения OCP? Поскольку, если создается новый тип, должно быть реализовано новое предложение else
2) Существует ли другой подход, чтобы поддерживать принцип SOLID OCP как для базы данных, так и для бизнес-кода без использования предложений switch ou if-else?

+0

Если вы строите инструкцию SQL, почему бы не использовать библиотеку и подготовленный оператор для обработки этих вещей для вас? – Seth

+0

Запрос создается через существующий пользовательский интерфейс, поэтому он должен поддерживать заполнители, определенные в шаблоне. Также он должен поддерживать каскадные запросы. Поэтому я решил создать свой собственный компонент. –

ответ

1

Replacing contionnal with polymorphysim гарантирует, что принятие решения произойдет только один раз, поэтому, вероятно, это хорошая идея. Если в какой-то момент у вас есть дополнительные специализированные операции по типу, их следует легко реализовать.

Теперь, для создания конкретных типов, вы можете инкапсулировать эту логику на заводе. В самой упрощенной форме завод будет статическим с большим оператором switch. Он не уважает OCP, но он по-прежнему является приемлемым дизайном большую часть времени.

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

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

E.g.

filterTypeFactory.RegisterFilter(1, typeof(FilterTypeInteger)); 

Во всяком случае, прежде чем вы отправитесь сами и создадите свой собственный SQL-оператор, вы должны посмотреть на существующие библиотеки. У вас может быть промежуточный DSL (ваши шаблоны), который анализируется в AST, а затем обрабатывает этот AST для создания SqlCommand или что-то в этом роде.

+0

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

+0

@ DaniloRuziska Принципы SOLID - это рекомендации, но вы должны оставаться прагматичными. Если статическая фабрика выполняет эту работу, то, вероятно, лучше придерживаться ее, а не строить очень сложный расширяемый механизм, который позволяет автоматически открывать новые типы фильтров, когда вам это не нужно. – plalx

+0

@plalx Бритва Оккама - хороший повод для «нарушающих» принципов. – CSharpie

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