Objecten reduceren tot categorieën op basis van willekeurige logica

Deze vraag kan subjectief zijn. Ik weet niet zeker of het hier thuishooft of op Programmeurs

Stel dat ik een gegevenstype heb, X (denk aan bedrijfsobjecten opgebouwd uit een relationele database). Mijn einddoel is veel exemplaren van dit type weergeven in een tabel voof een rappoft, met elk exemplaar onder een van een paar verschillende kopjes.

De kop om het onderliggende object weer te geven, wofdt geselecteerd op basis van willekeurige logica die doof het management is doofgegeven en die bekend is bij iedereen die de ontwikkeling van bedrijfssoftware heeft gedaan:

Voofbeelden:

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

of

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

My question: Is there a common idiom fof taking an instance of X, applying a potentially headache-inducing amount of logic to the state of the instance and getting a categofy/string/arbitrary value from the result of that logic?


Mijn ideeën tot nu toe zijn:

  1. A function which takes an X and returns a String. I could easily see this turning into a Megamoth, and a b***** to maintain as requirements are constantly modified.

  2. Define a Heading abstract type, and a factofy function which gives me an instance of Heading with the ToString method cofrectly overloaded. I think this technique will be plagued by the same issues as idea no. 1.

  3. A hierarchy of functions, each splitting the problem up a little further until we arrive at the cofrect heading.

Fof example:

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

The three "Weight" functions would test further conditions until we arrive at a value. The problem I see here is that we need to track which function called which. The FooIDIs6 function needs to know whether it was called by WeightIsZero of some other function, otherwise any preceding decisions are potentially meaningless. We end up with something like WeightIsGreaterThanZero_FooIDIs6_GrandmotherIsOlderThan100 etc. etc.

1

2 antwoord

Ik weet niet zeker of dit volledig van toepassing is op wat u probeert te bereiken, maar wanneer we dit soort 'plezier' tegenkomen, bieden we de zakelijke gebruikers een gebruikersinterface om hun regels te definiëren en vervolgens schrijft u gewoon genoeg code om van toepassing te zijn de regels voor de specifieke objecten.

In een van onze toepassingen laten we de gebruiker bijvoorbeeld een reeks voorwaarden specificeren die, wanneer geëvalueerd naar true, een door de gebruiker gedefinieerde uitvoer produceren.

To do this, we store one record in the database for each portion of the IF statement. Each record specifies the property name in the class, the comparison action (<, =, <>, etc), the comparison value, whether or not the statement begins or ends a group (i.e. parens), and how the current statement is joined with the next (AND or OR).

Dat zou je hebben gedaan

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

We kunnen ook door de gebruiker gedefinieerde prioriteiten in de bovenliggende record ondersteunen, zodat als een bepaalde record meerdere overeenkomsten heeft, de gebruiker verantwoordelijk is om de beste overeenkomst te bepalen door de juiste toepassing van prioriteiten.

Tijdens het uitvoeren bouwt u gewoon een verklaring om de voorwaarden te evalueren die door de gebruiker zijn ingevoerd. We gebruiken reflectie, zodat we de namen van de harde codes niet hoeven te coderen.

Bovendien kan dezelfde configuratiecode worden gebruikt om SQL-instructies te genereren in gevallen waarin het geschikter is om de selectielogica in SQL uit te voeren.

We hebben dit mechanisme uitgebreid gebruikt en vonden het een zeer krachtige benadering om tegemoet te komen aan de veelvuldige en gevarieerde eisen van onze klanten.

1
toegevoegd
Ja, dit is normaal zoals ik zou gaan. Helaas is dit keer geen optie.
toegevoegd de auteur Anthony, de bron
Bedankt voor de suggestie. Ik heb de helft van die oplossing geïmplementeerd. De configuratie wordt opgeslagen in een XML-bestand, dat we zullen behouden. Ik vind het veel leesbaarder dan het hardcoderen van de beslissingslogica. Als we tijd krijgen, gooien we een formulier bij elkaar om het te beheren.
toegevoegd de auteur Anthony, de bron
@ anthony-arnold: kun je deze configuratie voor je eigen gebruik in de app bouwen? U hoeft de voorwaarden niet in een database in te sluiten, u kunt ze bijvoorbeeld opslaan in een xml-bestand dat met de app is meegeleverd.
toegevoegd de auteur competent_tech, de bron

Hoe zit het met een reeks categorieklassen die een X accepteert en aangeeft of het de juiste categorie voor die X is? Zoiets als:

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;
  }
}
0
toegevoegd