Сокращение объектов до категорий на основе произвольной логики - PullRequest
1 голос
/ 07 декабря 2011

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

Скажем, у меня есть тип данных X (представьте себе бизнес-объекты, построенные из реляционной базы данных). Моя конечная цель - представить множество экземпляров этого типа в таблице для отчета, причем каждый экземпляр находится под одним из нескольких разных заголовков.

Заголовок для отображения объекта под выбран на основе произвольной логики, передаваемой из управления, с которой любой, кто занимался разработкой корпоративного программного обеспечения, будет знаком:

Примеры:

If the instance has a FooID of 6 and a BarFactor of < 0.5, place it under the "Borked" heading.

или

If the Weight is > 0, and the CreatedDate is before Midnight but after 3PM, and today is not the 3rd Wednesday of the month, the object should be categorised as "Fluffy".

Мой вопрос: существует ли распространенная идиома для взятия экземпляра X, применения потенциально вызывающего головную боль количества логики к состоянию экземпляра и получения категории / строки / произвольного значения из результата этой логики

<ч />

Мои идеи до сих пор были:

  1. Функция, которая принимает X и возвращает String. Я легко мог видеть, как это превращается в Мегамота , и b *****, чтобы поддерживать, поскольку требования постоянно изменяются.

  2. Определите абстрактный тип Heading и фабричную функцию, которая дает мне экземпляр Heading с корректно перегруженным методом ToString. Я думаю, что эта техника будет преследовать те же проблемы, что и идея нет. 1.

  3. Иерархия функций, каждая из которых разбивает проблему немного дальше, пока мы не придем к правильному заголовку.

Например:

public String GetHeading(X x) 
{
    if (x.Weight > 0)
        return WeightGreaterThanZero(x);
    else if (x.Weight < 0)
        return WeightLessThanZero(x);
    else
        return WeightIsZero(x);
}

Три функции «Вес» будут проверять дальнейшие условия, пока мы не получим значение. Проблема, которую я вижу здесь, заключается в том, что нам нужно отслеживать, какая функция называется какой. Функция FooIDIs6 должна знать, была ли она вызвана WeightIsZero или какой-либо другой функцией, иначе любые предыдущие решения потенциально бессмысленны. В итоге получается что-то вроде WeightIsGreaterThanZero_FooIDIs6_GrandmotherIsOlderThan100 и т. Д. И т. П.

Ответы [ 2 ]

1 голос
/ 07 декабря 2011

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

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

Для этого мы сохраняем одну запись в базе данных для каждой части оператора IF. В каждой записи указывается имя свойства в классе, действие сравнения (<, =, <> и т. Д.), Значение сравнения, независимо от того, начинается или заканчивается ли оператор группа (т. Е. Parens), и как присоединяется текущий оператор. со следующим (И или ИЛИ).

Так что вы бы

Heading Record (Parent record, which defines the heading to be used)
  Heading Selector (Child records which define the if statement)

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

Во время выполнения вы просто создаете оператор для оценки условий, введенных пользователем. Мы используем отражение, чтобы нам не приходилось жестко кодировать имена свойств.

Кроме того, тот же код конфигурации можно использовать для генерации операторов SQL в тех случаях, когда более целесообразно выполнять логику выбора в SQL.

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

0 голосов
/ 07 декабря 2011

Как насчет набора классов категорий, который принимает X и указывает, является ли это правильная категория для этого X?Что-то вроде:

var categories = new Category[] { new FooCategory(), new BarCategory(), new FluffyCategory() };

foreach( var x in myListOfXs ) {
  var cat = categories.FirstOrDefault(c => c.Matches(x));
  if( cat != null ) {
    x.Category = cat.Name;
  }
}
...