Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[ALG] use case omzetten naar code

Pagina: 1
Acties:
  • 116 views sinds 30-01-2008
  • Reageer

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
Ik ben bezig aan een MVC web-based applicatie, hiervoor moet ik volgende use case implementeren:

Bewaren Babysit : Hierin moeten de gegevens die de gebruiker ingegeven heeft (form gegevens) in de databank bewaard worden. Waarbij bijvoorbeeld een bijkomende test: indien deze babysit een adres heeft met een ongekend postnummer binnen de toepassing, dan moet er indien de gebruiker die babysit wil bewaren een boodschap op het scherm krijgen enkel en alleen als deze een geregistreerde gebruiker is, indien de gebruiker niet geregistreerd is moet er achter de schermen een mail verzonden worden naar een bepaald iemand.

Mijn vraag is nu hoe organiseer ik dit best over de verschillende lagen van mijn applicatie:

Zoals ik het nu heb: een Actie klasse die een methode : babysitservice.saveBabysit (nieuweBabysit) oproept. In deze actie klasse ga ik na het bewaren van de babysit nog volgende code uitvoeren (hier denk ik dat het verkeerd gaat, omdat nu mijn business logica (die in de use case staat) in mijn actie klasse komt te zitten, ik plaats dit hier omdat ik rechtstreeks een boodschap op het scherm moet geven aan de gebruiker of een mail sturen (beide niet zinnen in save methode van babysit denk ik.... en in mijn service laag heb ik geen notie van httprequest en dergelijke om een boodschap naar de gebruiker te geven)

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class BabysitAction...

//services 

public ActionForward perform(..., request, response, ...) {
 babysitservice.saveBabysit(nieuweBabysit);
 if (nieuweBabysit.heeftOngekendPostNummer()) {
   if (gebruiker.isGeregistreerd()) {
      //toon message op scherm ( = bv steek stukje tekst in de request, want in de actie klasse heb ik    hier toegang tot
   } else {
     mailService.stuurMailNaarIemand()
   }
 }
 return successForward;
}


Hoe gaan jullie om met dergelijke problemen, om deze toch nog zo logisch mogelijk bij elkaar te plaatsen ?

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Meer een algemene opmerking, kijk naar Exceptions. Maak een service met business granulariteit. Dus bijvoorbeeld: babysitService.nieuweBabysit(eenOfAndereVraagTO) throws OnbekendPostnummerException, NogEenException, BlaException, NietUniekException;

Geef elke Exception een bepaalde property, bijv: een key uit een ResourceBundle, en lees die in je catch block in de weblaag uit. Eventueel op een generieke manier.

Dat generieke kun je in Struts (voorbeeld ziet er tenminste uit als Struts) eventueel voor elkaar krijgen door een BaseAction te maken en daar de Exception logica in te zetten.

Is dat al een antwoord in de goede richting?

Fat Pizza's pizza, they are big and they are cheezy


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
Dergelijk systeem met generieke excepties heb ik nu, maar ergens in mijn achterhoofd zegt een stemmetje dat je je logica niet afhankelijk mag maken van je excepties...

met het huidig systeem die ik nu heb zou ik dan in mijn weblaag (Action klasse) afhankelijk van de exceptie die ik ontvang een bepaalde UseCase stap moeten gaan uitvoeren. Lijkt met toch niet zo'n nette noch onder houdbare manier van werken ?

Volgens de documentatie in de use case is het zenden van mail of boodschap tonen aan de gebruiker allemaal onderdeel van dezelfde case, nl. het bewaren van een babysit... in het voorbeeld wat ik gepost heb kan je dit al minder goed terug vinden omdat de verschillende onderdelen van de use case nu verspreid zitten over verschillende klassen..

[ Voor 29% gewijzigd door Cuball op 14-08-2007 18:14 ]

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Cuball schreef op dinsdag 14 augustus 2007 @ 18:11:
Dergelijk systeem met generieke excepties heb ik nu, maar ergens in mijn achterhoofd zegt een stemmetje dat je je logica niet afhankelijk mag maken van je excepties...
Het is een stukje smaak, maar ik vind bijvoorbeeld een record dat al bestaat terwijl ik het toevoeg, een exceptioneel geval. Op zo'n moment gooi ik ook een exception. In jouw geval zul je moeten bepalen of een bepaald scenario exceptioneel is (in feite dus een foutscenario) of dat het gewoon een logische stap is in de use case.

Ik redeneer nu vanuit service perspectief. Daar bepaal je wat je regels zijn. Eventueel kun je je returntypes, argumenten en exceptions slim opzetten zodat je weblaag zich niet in bochten hoeft te wringen om er iets mee te kunnen. (ik zet bijvoorbeeld in een exception altijd een foutcode die ik gemakkelijk in een properties file kan zetten, dat scheelt weer een mapping)
met het huidig systeem die ik nu heb zou ik dan in mijn weblaag (Action klasse) afhankelijk van de exceptie die ik ontvang een bepaalde UseCase stap moeten gaan uitvoeren. Lijkt met toch niet zo'n nette noch onder houdbare manier van werken ?
Het zullen sowieso meerdere method calls worden verwacht ik. Je moet alleen steeds bedenken of iets business logica is of navigatie logica. Mijn voorbeeld van het toevoegen van een record dat al bestaat is vanuit business logica perspectief gewoon een foutgeval. Vanuit het oogpunt van de gebruiker komen daar soms nog wat extra zaken bij, bijvoorbeeld het navigeren naar een andere pagina ofzo. Als je consequent business en navigatie logica op de juiste plaats zet wordt het vanzelf onderhoudbaar (natuurlijk moet je ook met andere zaken rekening houden zoals separation of concerns, maar dat terzijde).

Als je goed tussen de regels doorleest, zie je dat dit in feite ook een vorm van separation of concerns is. Het is overigens niet alleen een opdeling op basis van domein (verantwoordelijkheid), maar ook op basis van lifecycle. Web is niet afhankelijk van bijv. Hibernate, alleen maar van het feit dat je iets doet dat volgens het domein niet toegestaan is, of je doet iets dat volgens het domein een bepaald resultaat heeft. Releases van web zijn dan veel minder afhankelijk van een specifieke service versie en visa versa, want de service kan ervan uitgaan dat web alleen maar afhankelijk van een business rule die al jaren bekend is.
Volgens de documentatie in de use case is het zenden van mail of boodschap tonen aan de gebruiker allemaal onderdeel van dezelfde case, nl. het bewaren van een babysit... in het voorbeeld wat ik gepost heb kan je dit al minder goed terug vinden omdat de verschillende onderdelen van de use case nu verspreid zitten over verschillende klassen..
Het is een stukje smaak, en er zijn altijd twijfelgevallen, maar probeer altijd een naam in je service te gebruiken die voor de business betekenis heeft. Zo creeer je vanzelf onafhankelijkheid en een stukje onderhoudbaarheid. Exception of return type maakt op zich niet veel uit. Het zijn andere taalconstructies. Als je iets in je use case beschrijft als een uitzondering of fout, wil ik mijn 'gewone' flow er niet mee vervuilen en gebruik ik een try catch (of throw). Als het een typische stap is in de use case, dan gebruik ik een if.

Om terug te komen op jouw use case. Zoals ik het lees, is "nieuweBabysit.heeftOngekendPostNummer()" een foutscenario. Je kunt immers de boel niet opslaan als dit het geval is. Het feit dat je in je weblaag de gebruiker tegemoetkomt door het tonen van foutmeldingen of sturen van e-mails doet daar niets aan af.

Als het geen echt foutscenarion is, gewoon if-else constructie.

Maar misschien zie ik jouw use case wel helemaal verkeerd. Ik snap ook niet waarom je een save actie doet voordat je checkt op de postcodes en zo.

Fat Pizza's pizza, they are big and they are cheezy


  • MisterBlue
  • Registratie: Mei 2002
  • Laatst online: 07:17
Ben niet zo bekend met Struts, maar je kunt ook kijken naar hoe dit in Ruby on Rails werkt. Het zit er namelijk standaard in.
Het model heeft daar de logica van validatie en vult een error collectie als er validatie fouten zijn. De save geeft dan een false terug en de controller kan dan de boodschappen uit de error collectie halen om te tonen in de view.
Het versturen van de mail zou je dan in het model kunnen doen als onderdeel van je validatie. Als je dit niet in je model wil plaatsen om het clean te houden, kun je in rails een observer gebruiken die luistert naar een after_validate callback en dan de alert stuurt.

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
JKVA schreef op dinsdag 14 augustus 2007 @ 19:24:
[...]

Het is een stukje smaak, maar ik vind bijvoorbeeld een record dat al bestaat terwijl ik het toevoeg, een exceptioneel geval. Op zo'n moment gooi ik ook een exception. In jouw geval zul je moeten bepalen of een bepaald scenario exceptioneel is (in feite dus een foutscenario) of dat het gewoon een logische stap is in de use case.
daar ben ik het mee eens, dat is bij ons ook een exceptie. Normaal gezien zou deze fout niet mogen voorkomen, maar wat als dergelelijke fout in de use case beschreven staat en er een alternatieve flow gestart wordt... dan ben ik geneigd om eerst wat code te schrijven die effectief controleert of er geen dubbele record bestaat ipv te wachten op een exceptie vanuit de databank...
Ik redeneer nu vanuit service perspectief. Daar bepaal je wat je regels zijn. Eventueel kun je je returntypes, argumenten en exceptions slim opzetten zodat je weblaag zich niet in bochten hoeft te wringen om er iets mee te kunnen. (ik zet bijvoorbeeld in een exception altijd een foutcode die ik gemakkelijk in een properties file kan zetten, dat scheelt weer een mapping)
dat heb ik nu ook, een key die dan uit een Resource Bundle gelezen wordt, op deze manier heb je foutmeldingen met i8n support :-)
Het zullen sowieso meerdere method calls worden verwacht ik. Je moet alleen steeds bedenken of iets business logica is of navigatie logica. Mijn voorbeeld van het toevoegen van een record dat al bestaat is vanuit business logica perspectief gewoon een foutgeval. Vanuit het oogpunt van de gebruiker komen daar soms nog wat extra zaken bij, bijvoorbeeld het navigeren naar een andere pagina ofzo. Als je consequent business en navigatie logica op de juiste plaats zet wordt het vanzelf onderhoudbaar (natuurlijk moet je ook met andere zaken rekening houden zoals separation of concerns, maar dat terzijde).
daar heb je gelijk in, maar ik programmeer niet alleen, hoe beschrijf je dergelijk zaken zonder dat elke programmeur er zijn eigen interpretatie van maakt... toch vind ik het sturen van een mail vanuit mijn actie klasse niet zo'n nette oplossing.
Maar misschien zie ik jouw use case wel helemaal verkeerd. Ik snap ook niet waarom je een save actie doet voordat je checkt op de postcodes en zo.
Een geldig postcode is niet in de aard van een bestaande postcode, maar wel of het al dan niet gekend is binnen de toepassing... het saven van een babysit kan perfect zonder dat haar postcode gekend is binnen de toepassing, maar afhankelijk van dat en de ingelogde gebruiker wordt er een mail of bericht op het scherm getoond..

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 28-11 14:44
MisterBlue schreef op donderdag 16 augustus 2007 @ 07:53:
Ben niet zo bekend met Struts, maar je kunt ook kijken naar hoe dit in Ruby on Rails werkt. Het zit er namelijk standaard in.
Het model heeft daar de logica van validatie en vult een error collectie als er validatie fouten zijn. De save geeft dan een false terug en de controller kan dan de boodschappen uit de error collectie halen om te tonen in de view.
Struts heeft ook een standaard messages systeem (ActionMessages) ik denk dat dit overeenkomt met wat je vergelijk bij Ruby (ken ik wel totaal niet)
Het versturen van de mail zou je dan in het model kunnen doen als onderdeel van je validatie. Als je dit niet in je model wil plaatsen om het clean te houden, kun je in rails een observer gebruiken die luistert naar een after_validate callback en dan de alert stuurt.
ik zou nu ook een observer kunnen gebruiken om een mail te sturen, maar in mijn weblaag ben is dit nutteloos...

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • MisterBlue
  • Registratie: Mei 2002
  • Laatst online: 07:17
Met het gevaar te overengineeren: je zou ook een interface of abstracte class kunnen gebruiken en een aparte concrete GebruikerIsGeregistreerdActies class en een aparte GebruikerIsNietGeregistreedActies class. Dan vermijd je in elk geval wat if-then-else constructies.

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

MisterBlue schreef op donderdag 16 augustus 2007 @ 11:02:
Met het gevaar te overengineeren: je zou ook een interface of abstracte class kunnen gebruiken en een aparte concrete GebruikerIsGeregistreerdActies class en een aparte GebruikerIsNietGeregistreedActies class. Dan vermijd je in elk geval wat if-then-else constructies.
Mja, maar met hooguit 2 cases lijkt het me idd overengineering. Mailtjes sturen vanuit een weblaag ben ik ook geen fan van. Sterker nog, ik vind het zelfs bij een persist/dao laag horen. Dat laatste is misschien extreem, maar daar ben ik de laatste tijd aan gewend geraakt op mijn huidige opdracht waar we een complete print/mail/sms/etc straat hebben. Alle vormen van output naar externe systemen in een dao (zoals in mijn huidige project) bevalt me eigenlijk wel goed.

Fat Pizza's pizza, they are big and they are cheezy

Pagina: 1