[ALG] Versturen producten aan de hand van condities

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik weet niet goed of ik de goede kant op ga en ik hoop dat iemand mij verder kan helpen.

De situatie is als volgt:
Een verzameling van producten kan naar een klant verstuurd worden maar niet alle klanten krijgen dezelfde producten. Een conditie bepaald uiteindelijk of een product naar een klant wordt gestuurd. Als er geen conditie is voor een product dan wordt het product altijd opgestuurd.

Stom voorbeeld:
Een introductie doos bevat
- Shampoo
- Spiegel (als geslacht == vrouw)
- Scheerapparaat (als geslacht == man)
- Speelgoed auto (als leeftijd <= 12)

Mijn idee was om het als volgt op te zetten.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
** Products **
----------------------------------
ID  | Name
----------------------------------
1   | Shampoo
2   | Spiegel
3   | Scheerapparaat
4   | Speelgoed auto

** Product_Conditions **
-----------------------------------------------------
ID  | ProductID | Condition
-----------------------------------------------------
1   | 2         | Gender == 0
2   | 3         | Gender == 1
3   | 4         | Age <= 12


Ik weet alleen nog niet goed hoe ik de mapping dan ga maken tussen de database en het daadwerkelijke systeem. Ik kan de conditionele parameters in code hardcoden maar dan weet ik nog niet hoe de boel gemapped is. Eigenlijk wil ik kunnen bepalen waar de conditie mee vergeleken moet worden en dan niet alleen op type niveau (bool, DateTime, etc.) maar ook vanuit welk object (person.Gender, person.DateOfBirth, etc.).

Is dit logisch of zijn er betere manieren om dit voor elkaar te krijgen. Het voelt niet helemaal goed aan maar ik heb geen idee hoe ik het anders voor elkaar ga krijgen. Nadeel van mijn methode is dat fouten heel makkelijk te maken zijn. Ik heb ook het idee dat het nog best een lading werk is om dit knap te gaan coden.

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Tony L schreef op donderdag 16 april 2009 @ 11:23:
Ik weet alleen nog niet goed hoe ik de mapping dan ga maken tussen de database en het daadwerkelijke systeem. Ik kan de conditionele parameters in code hardcoden maar dan weet ik nog niet hoe de boel gemapped is. Eigenlijk wil ik kunnen bepalen waar de conditie mee vergeleken moet worden en dan niet alleen op type niveau (bool, DateTime, etc.) maar ook vanuit welk object (person.Gender, person.DateOfBirth, etc.).

Is dit logisch of zijn er betere manieren om dit voor elkaar te krijgen. Het voelt niet helemaal goed aan maar ik heb geen idee hoe ik het anders voor elkaar ga krijgen. Nadeel van mijn methode is dat fouten heel makkelijk te maken zijn. Ik heb ook het idee dat het nog best een lading werk is om dit knap te gaan coden.
Ik zou in ieder geval je conditie-kolom verder uitsplitsen, bijvoorbeeld in subject, operator, object. Verder kun je je afvragen welke delen van dit verhaal echt dynamisch zijn. Moet je echt op alle mogelijke eigenschappen kunnen selecteren? Ik kan me goed voorstellen, als het maar een paar condities betreft die niet vaak veranderen, dat je dit gewoon hard-coded doet.

Rustacean


Acties:
  • 0 Henk 'm!

  • twiekert
  • Registratie: Februari 2001
  • Laatst online: 06:58
En daarnaast krijg je mischien ook wel meerdere condities per product, en AND / OR constructies. De daadwerkelijk check zou ik in de code programmeren en de parameters opslaan in de DB.

Acties:
  • 0 Henk 'm!

  • Tony L
  • Registratie: September 2005
  • Laatst online: 07-11-2015
Ik denk dat jullie gelijk hebben. Het gaat erg complex worden op het moment dat je dit verder gaat uitbouwen.

Mijn huidige idee is om de parameters in de database in te bakken en deze in code uit te lezen:

code:
1
2
3
4
5
6
7
8
** Products **
--------------------------------------------------------------------------
ID  | Name          | Gender        | Age
--------------------------------------------------------------------------
1   | Shampoo           | NULL      | NULL
2   | Spiegel           | 1         | NULL
3   | Scheerapparaat    | 0         | NULL
4   | Speelgoed auto    | NULL      | 12


Alleen dit ziet er ook niet uit... En sowieso komen er dan veel lege cellen waar je ook niet echt op zit te wachten. En complexe condities krijg je hier ook niet mee opgelost (in hoeverre je die hiermee wilt oplossen).

Ik zal mijn probleem verder beschrijven. Het is mogelijk om meerdere dozen samen te stellen, bijvoorbeeld:

Doos 1
  • Shampoo
  • Spiegel (Gender == Vrouw)
  • Scheerapparaat (Gender == Man)
  • Speelgoed auto (Age <= 12)
Doos 2
  • Kerstbrood
  • Lipstick (Gender == Vrouw)
  • Aftershave (Gender == Man)
  • Speelgoed auto (Age <= 12)
Ik kan de dozen dus niet hard-coden omdat ze uitbreidbaar zijn. Het is mogelijk om nieuwe dozen toe te voegen en te wijzigen. Is er geen design pattern die dit op kan lossen?

PSN: Norfirin


Acties:
  • 0 Henk 'm!

  • twiekert
  • Registratie: Februari 2001
  • Laatst online: 06:58
Ik zou die controles ook los trekken zoals dit:


code:
1
2
3
4
5
6
7
8
9
10
11
Product table:
ID        Name          
1         Shampoo     
2         Spiegel
3         Scheerapp

ProductConditions tabel:
ID         ProductID    Check                   Parameter1  Parameter2         
1           1                AgeGreaterThan     12                NULL
2           2                Gender                  F                 NULL
3           3                Gender                  M                NULL


of als je echt veel less/greater than en equal condities hebt kan het ook nog zo:
code:
1
2
3
4
Check        Parameter1          Parameter2
Age           lessthan               12
Age           equals                  20
...etc..


De hoeveelheid parameters en het type var bepaal je in de code en zal je daar dan moeten typecasten. de implementatie van die check maak je dus ook in de code en hiermee kan je dus ook complexere validaties doen, enig nadeel is dat je genoeg parameter kolommen moet maken en je geen type kan definieren (of je moet parameters ook weer in een losse table stoppen, maar dat lijkt me wat overkill)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function validateCheckAge(Person p, type, age) {
  age= (int) age;

  switch (type) {
      case "lessthan":
          return (p.getAge() < age);
      case "greaterthan":
         return (p.getAge() > age);
      case "equals": 
        return (p.getAge() == age);
      default:
         throw new CheckException("Invalid type given:"+ type);
  }
  
  
}


Nu kan je ook in een later stadium meerdere condities per product toepassen en gaan groeperen. En je kan op die produktsamenstellingen ook al voorwaarden gaan definieren welke producten hier in mogen met behulp van een lijst van beschikbare checks.

Acties:
  • 0 Henk 'm!

Verwijderd

Lol,

Wat ook nog zou kunnen :

Kies een ID voor je produkten die 'slim is'.


een produktID wordt dan als volgt

ddddxxxyyyznnnn

waarbij dddd = doosID, xxx = minimale leeftijd, yyy=maximale leeftijd en z is 1 voor vrouw en 2 voor man en 0 voor maakt niet uit

voor je eerste voorbeelddoos zijn de produkten dan als volgt : (met tussenstreepjes voor leesbaarheid!)


1000-000-999-0-0001 Shampoo
1000-000-999-1-0002 Spiegel
1000-000-999-2-0003 Scheerapparaat
1000-000-012-0-0004 Speelgoed auto

Je kan dan zelf wel verzinnen wat de 'slimme' code moet zijn om een doos van 'type 1000' te vullen is :)


(ik ben niet zo goed met de forum opmaak codes zoals je ziet.......sorry daarvoor)

Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 18-08 21:31
Houd je er ook rekening mee dat soms meerdere condities geldig kunnen zijn? Zoals het meisje van 11 dat lipstick en een speelgoedauto krijgt?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op dinsdag 28 april 2009 @ 16:29:
Lol,

Wat ook nog zou kunnen :

Kies een ID voor je produkten die 'slim is'.


een produktID wordt dan als volgt

ddddxxxyyyznnnn

waarbij dddd = doosID, xxx = minimale leeftijd, yyy=maximale leeftijd en z is 1 voor vrouw en 2 voor man en 0 voor maakt niet uit

voor je eerste voorbeelddoos zijn de produkten dan als volgt : (met tussenstreepjes voor leesbaarheid!)


1000-000-999-0-0001 Shampoo
1000-000-999-1-0002 Spiegel
1000-000-999-2-0003 Scheerapparaat
1000-000-012-0-0004 Speelgoed auto

Je kan dan zelf wel verzinnen wat de 'slimme' code moet zijn om een doos van 'type 1000' te vullen is :)


(ik ben niet zo goed met de forum opmaak codes zoals je ziet.......sorry daarvoor)
Het idee is leuk, maar toch maar niet. Het gaat namelijk tegen een paar database regeltjes in:
1 - Nooit betekenis aan een ID geven
2 - Nooit gegevens gaan aggregeren in een enkele kolom

Wat wil je bijvoorbeeld doen bij de 10000-e doos?
Wat als er een extra conditie bij komt?
Tony L schreef op donderdag 16 april 2009 @ 14:17:
code:
1
2
3
4
5
6
7
8
** Products **
--------------------------------------------------------------------------
ID  | Name          | Gender        | Age
--------------------------------------------------------------------------
1   | Shampoo           | NULL      | NULL
2   | Spiegel           | 1         | NULL
3   | Scheerapparaat    | 0         | NULL
4   | Speelgoed auto    | NULL      | 12


Alleen dit ziet er ook niet uit... En sowieso komen er dan veel lege cellen waar je ook niet echt op zit te wachten. En complexe condities krijg je hier ook niet mee opgelost (in hoeverre je die hiermee wilt oplossen).
Wat is je probleem met de lege cellen? Zo 'lelijk' is het niet. Als je eventueel nog minAge en maxAge gebruikt in plaats van age kom je denk ik een heel eind.

Zoals al eerder aangegeven is het probleem vooral hoe flexibel je het wil maken. Verwacht je nog meer uitgebreide condities (bijvoorbeeld, mensen die uit Friesland komen en ouder zijn dan 18 krijgen een flesje beerenburg erbij), dan heeft het zin om een evaluator te maken die met een weggeschreven expressie om kan gaan (je zult het dan niet meer op kunnen lossen in enkel je database).

Wil je het efficient in de database houden, dan zul je vooraf je expressies moeten bepalen en het samenstellen hiertoe beperken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Daar moet je dus rekening mee houden met het opzetten van je ID's.

Een architectuur maak je voor "altijd". Dus als het later niet past, heb je niet goed nagedacht OF gebruik je je spullen verkeerd :)

Maar inderdaad. Misschien beter om op te delen.

Als je al je condities met JA/NEE wilt kunne afvangen is het het best om een binary te nemen. Je kan dan lekker xorren en nanden enzo om het snel te selecten :)

Maar goed, terugkomend op het oorspronkelijke probleem,

Misschien beter om het inderdaad te hardcoden. Of declaratief te programmeren :) php is daar niet zo'n kei in :)
En een prolog module heb ik nog niet gezien voor bijv. apache :)

het klinkt een beetje als een softwarematige couverteermachine. Dat soort dingen werken altijd met 'streepjescodes' wat eigenlijk een 'hardware implementatie' is van mijn eerder genoemde 'slimme ID'.


succes!

Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Verwijderd schreef op dinsdag 28 april 2009 @ 21:02:
Daar moet je dus rekening mee houden met het opzetten van je ID's.
Gefeliciteerd, je hebt net een database in je database gemaakt....

Over het onderwerp zelf:
Als je condities voor verzenden (kunnen) gaan wijzigen en ook volledig anders kunnen worden, dan zou je kunnen overwegen om een DSL met bijbehorende parser te maken (of een bestaande rule-engine met bijbehorende DSL). De tekst van de DSL neem je dan op zoals je nu ook hebt en verwerk je door middel van je parser of rule-engine.

Als de bestaande voorwaarden blijven voor wat ze zijn of slechts sporadisch gaan wijzigen, dan zou ik gewoon voor de oplossing van Twiekert gaan. Je moet dan alleen goed opletten hoe je omgaat met meervoudige condities (altijd als AND of altijd als OR behandelen, of extra logica toevoegen om dat instelbaar te maken)

Acties:
  • 0 Henk 'm!

Verwijderd

Remus schreef op woensdag 29 april 2009 @ 08:45:
Gefeliciteerd, je hebt net een database in je database gemaakt....
Daar begon het hele vraagstuk toch al mee :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op woensdag 29 april 2009 @ 10:57:
[...]


Daar begon het hele vraagstuk toch al mee :)
Nee. Het vraagstuk gaat over hoe bepaalde condities vast te leggen. Serieus, je systeem lijkt een slimme oplossing en hij is vroeger ook wel toegepast, maar bij veel van dergelijke legacy systemen is men daar keihard op terug gekomen. Te weinig ruimte ingeschat, onleesbare database vulling, onnodig geintroduceerde afhankelijkheden, geen mogelijkheid tot conversie en onnodig opgelegde beperkingen zijn slechts enkele problemen waar dit soort systemen mee kampen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Verwijderd schreef op woensdag 29 april 2009 @ 10:57:
[...]
Daar begon het hele vraagstuk toch al mee :)
Ik verwijs naar het feit dat jij het handig vindt om betekenisvolle, gestructureerde IDs te maken, waarmee je effectief een geneste gegevensstructuur in je database opneemt, ofwel een database in je database.
Ik geef de voorkeur aan genormaliseerde data opslaan in mijn databases.

Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Janoz schreef op dinsdag 28 april 2009 @ 16:59:
1 - Nooit betekenis aan een ID geven
Dit is een beetje een dubieuze regel. Ik weet niet hoe jij het precies bedoelt, maar het hebben van een zinvolle primary key is juist behoorlijk handig. E.g. usernames als pkey ipv een zinloos nummertje; door numerieke ID's te gebruiken waar je in feite juist constraints hebt op andere kolommen kom je alleen maar in de problemen (er zijn helaas veel te veel mensen, met name onder de PHP/MySQL crowd, die dit doen).

Neemt niet weg dat het opnemen van gestructueerde data in een database-cel over het algemeen problematisch is (jouw regel 2).

Rustacean


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

djc schreef op woensdag 06 mei 2009 @ 11:06:
[...]
Dit is een beetje een dubieuze regel. Ik weet niet hoe jij het precies bedoelt, maar het hebben van een zinvolle primary key is juist behoorlijk handig. E.g. usernames als pkey ipv een zinloos nummertje; door numerieke ID's te gebruiken waar je in feite juist constraints hebt op andere kolommen kom je alleen maar in de problemen (er zijn helaas veel te veel mensen, met name onder de PHP/MySQL crowd, die dit doen).
Ik volg je niet helemaal, maar wil je beweren dat het handig is om username als primary key te nemen? Veel succes met het aanpassen van alle door die gebruiker geplaatste berichten in het forum wanneer hij zijn gebruikersnaam eens aan wil passen....

Als je de gebruikersnaam uniek wilt houden, zet je een unique constraint op de kolom. Daarvoor misbruik je niet de PK.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
djc schreef op woensdag 06 mei 2009 @ 11:06:
[...]
Dit is een beetje een dubieuze regel. Ik weet niet hoe jij het precies bedoelt, maar het hebben van een zinvolle primary key is juist behoorlijk handig. E.g. usernames als pkey ipv een zinloos nummertje; door numerieke ID's te gebruiken waar je in feite juist constraints hebt op andere kolommen kom je alleen maar in de problemen (er zijn helaas veel te veel mensen, met name onder de PHP/MySQL crowd, die dit doen).

Neemt niet weg dat het opnemen van gestructueerde data in een database-cel over het algemeen problematisch is (jouw regel 2).
Ik ken voldoende systemen waar de gebruikersnaam aangepast kan worden. Als de gebruikersnaam dan de primary key is moet dit of handmatig worden aangepast (als het dbms geen foreign keys kent *cough* mysql met MyISAM) of waar de ON UPDATE CASCADE op de foreign key voor veel load zorgt. Daarnaast zijn indices op betekenisloze keys over het algemeen kleiner wat voordelen heeft bij het optimizen van de queries.

Daarnaast ken ik ook systemen waarbij usernames alleen unique hoeven te zijn voor actieve (niet-'gearchiveerde' gebruikers). Probeer dan nog maar eens een primary key op te leggen (en in zo'n geval gaan requirements toch echt voor implementatie).

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik ben het inderdaad eens met de heren hierboven je moet nooit een PK met enige betekenis ( behalve het uniek identificeren van het record ) gebruiken.

Dingen die op dit moment uniek lijken, en nooit veranderd gaan worden, kunnen dat in de toekomst misschien wel, en dan heb je een probleem.

Zo kun je in een database met personen bijvoorbeeld een BSN gebruiken, die gaan in princiepe nooit veranderen. Totdat de overheid over x jaar opeens beslist dat ze een ander identificatie systeem voor de burgers gaan gebruiken. Dan moet je of overal in je database waar je naar die personen verwijst de PK aan gaan passen, of je moet dan alsnog gebruik blijven maken van een BSN, die nieuwe mensen in je DB misschien wel niet meer hebben.

Een Unique constraint is immers makkelijk weg te halen, maar een PK veranderen is meestal niet zo makkelijk.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Janoz schreef op woensdag 06 mei 2009 @ 11:14:
Ik volg je niet helemaal, maar wil je beweren dat het handig is om username als primary key te nemen? Veel succes met het aanpassen van alle door die gebruiker geplaatste berichten in het forum wanneer hij zijn gebruikersnaam eens aan wil passen....
Een username is misschien niet een ideaal voorbeeld, maar het in alle gevallen toevoegen van een integer column alleen maar om te zorgen dat de rijen uniek worden is een recept voor problemen. Sla er gerust eens een boek over relationele calculus op na.

Rustacean


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
djc schreef op donderdag 07 mei 2009 @ 11:27:
[...]
Een username is misschien niet een ideaal voorbeeld, maar het in alle gevallen toevoegen van een integer column alleen maar om te zorgen dat de rijen uniek worden is een recept voor problemen. Sla er gerust eens een boek over relationele calculus op na.
Ik zie niet zo in hoe dat een recept voor problemen is? Een PK wil je nu eenmaal nooit wijzigen, en data die enige betekenis heeft, heeft grote kans dat hij later nog eens gewijzigd moet worden.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21-09 21:47

Creepy

Tactical Espionage Splatterer

Eeh, het toevoegen van die extra kolom is om een betekenisloze primary key te hebben. Niet om ervoor te zorgen dat de rij uniek identificeerbaar is, dat is een bijkomstigheid van de primary key.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1