Hej!Tänkte få lite synpunkter på att använda entitymanager från factory för att skapa en entity. (Hittade ingen factory som gör detta i DDDSample)
Mitt resonemang går ungefär såhär:
En entity jämförs uteslutande på ID, det är en del av att vara valid.Därför måste factory:n som skapar entity:n sätta ID.
Det beror p� vilka patterns man anv�nder. Exempelvis om du anv�nder
EventSourcing s� m�ste id't genereras av kommandot och anv�ndas som
input till eventet, som i sin tur skapar entity med det id't. Annars
funkar inte replay.
> I praktiken vill man generera ID fr�n databas, och allts� vill jag
> anv�nda EntityManagern f�r att generera ID.
I praktiken har jag alltid anv�nt en UUID generator. Se ovan. Och jag
skiljer mellan id'n f�r datanbaser och f�r m�nniskor. Exempelvis
order-id �r f�r m�nniskor, och kan d�rf�r s�ttas n�r ordern �r bekr�ftad
-> inga h�l i sekvensen. Funkar finfint.
> - Vi har ingen garanti f�r att orderId faktiskt anv�nds (att motsvarande
> order persisteras), vilket skapar h�l i orderid-sekvensen, vilket st�r
> administrat�rer (Men det kan vi egentligen aldrig garantera)
Se ovan!
> - Persistens-kod hamnar p� tv� olika st�llen, OrderFactory och
> OrderRepository.
OrderFactory och OrderRepository �r v�l interface, s� borde kunna
implementeras av samma objekt?
/Rickard
>
> Och jag skiljer mellan id'n för datanbaser och för människor.
Instämmer, jag försöker undvika att ge tekniska konstruktioner
domänlogisk mening.
> Exempelvis order-id är för människor, och kan därför sättas
> när ordern är bekräftad -> inga hål i sekvensen. Funkar finfint.
>
>> - Persistens-kod hamnar på två olika ställen, OrderFactory och
>> OrderRepository.
>
> OrderFactory och OrderRepository är väl interface, så borde kunna
> implementeras av samma objekt?
Ja, och interfacen kan ligga i paket xyz.domain medan implementationen
ligger i xyz.infrastructure.sqldb el likn. Så blir xyz.domain helt
fritt från referenser till specifik infrastruktur och kan t ex
enhetstestas utan annat på classpath.
Dan
> /Rickard
>
> --
> Det här meddelandet skickas till dig eftersom du prenumererar på gru
> ppen DDD Sverige i Google Groups.
> Om du vill göra ett inlägg i den här gruppen skickar du e-post till dddsverige@googlegroups.
> com.
> Om du vill sluta prenumerera på den här gruppen skickar du e-post ti
> ll dddsverige+...@googlegroups.com.
> För fler alternativ, besök gruppen på http://groups.google.com/group/dddsverige?hl
> =sv.
>
> Ja, och interfacen kan ligga i paket xyz.domain medan implementationen ligger i xyz.infrastructure.sqldb el likn. Så blir xyz.domain helt fritt från referenser till specifik infrastruktur och kan t ex enhetstestas utan annat på classpath.
Va? Enhetstestar du interfacet? ;-)
Mvh
Niclas
Visserligen dokumenterar jag gärna interfacet med enhetstester, men
det var inte riktigt det jag hade i åtanke.
Jag tänkte främst på att andra klasser som har beroenden till fabrik
och repository inte behöver några utåtgående beroenden som i sin
tur sprider sig till en massa andra paket. Istället blir domänpaketet
självinnehållande.
Dan
>
Ja, och interfacen kan ligga i paket xyz.domain medan implementationen ligger i xyz.infrastructure.sqldb el likn. Så blir xyz.domain helt fritt från referenser till specifik infrastruktur och kan t ex enhetstestas utan annat på classpath.
Va? Enhetstestar du interfacet? ;-)
Visserligen dokumenterar jag gärna interfacet med enhetstester, men det var inte riktigt det jag hade i åtanke.
Jag tänkte främst på att andra klasser som har beroenden till fabrik och repository inte behöver några utåtgående beroenden som i sin tur sprider sig till en massa andra paket. Istället blir domänpaketet självinnehållande.
--
Det här meddelandet skickas till dig eftersom du prenumererar på gruppen DDD Sverige i Google Groups.
Om du vill göra ett inlägg i den här gruppen skickar du e-post till dddsv...@googlegroups.com.
Om du vill sluta prenumerera på den här gruppen skickar du e-post till dddsverige+...@googlegroups.com.
I praktiken har jag alltid använt en UUID generator. Se ovan. Och jag skiljer mellan id'n för datanbaser och för människor. Exempelvis order-id är för människor, och kan därför sättas när ordern är bekräftad -> inga hål i sekvensen. Funkar finfint.
OrderFactory och OrderRepository är väl interface, så borde kunna implementeras av samma objekt?
- Persistens-kod hamnar på två olika ställen, OrderFactory och
OrderRepository.
I mina system har ALLA entities ALLTID ett UUID som identitet, ur ett
tekniskt perspektiv. Sedan har vi "�rendeid" (vi g�r Case Management),
personnr, och lite annat f�r s�kning och presentation, men det �r HELT
andra usecase.
/RIckard
4 nov 2010 kl. 10.13 skrev Jonas Andersson <jona...@gmail.com>:
> I praktiken har jag alltid använt en UUID generator. Se ovan. Och ja
> g skiljer mellan id'n för datanbaser och för människor. Exempelvis
> order-id är för människor, och kan därför sättas när ordern
> är bekräftad
>
>
> Det känns inte riktigt rätt för mig, en orders identet bestäms ju
> då inte längre av orderid, vilket jag tycker att den borde (Å
> andra sidan är jag fortfarande jag, oavsett vad mitt personnr är). M
> åste fundera mer på det.
Jag brukar tänka på det som att orderid är ett verksamhetsattribut,
vilket som helst. Sedan finns det attribut eller kombinationer av
attribut som unikt pekar ut (högst) en entitet - i vissa .NET-kretsar
har jag hört sådana uppsättningar kallas "determinanter".
> Instinktivt ogillar jag också att en Entity innehåller saker av "ren
> t teknisk" natur, vilket ju UUID blir - Ordern blir inte lika "ren".
> Men det löser onekligen upp beroendet mellan Factory och EntityMana
> ger.
Egentligen ät uuid bara ett implementationstrick. Tänk att vi hade en
oändlig minnes-heap på en krashsäker dator som aldrig behövde
startas om. Då skulle varje objekt identifieras av den minnesadress
den låg på och inga uuid skulle behövas. Däremot skulle en order
fortfarande ha sitt verksamhetsmässiga orderid.
Nu har vi ingen sådan heap utan måste spara ner våra objekt i
diverse persistensmekanismer. Då är uuid bara ett trick för att
spara och återskapa objektet - egentligen bara en "minnesadress" i det
oändliga persistensminnet.
När jag tänker på det sättet känns det inte så stötande att det
finns ett "tekniskt" attribut i en entitetsimplementation. Åtminstone
inte mer stötande än att en service av tekniska skäl skulle kunna
hålla en Connection eller Socket öppen under lite längre tid.
Dan
Exemplet med personnummer är bra (och om jag inte minns fel används
det av Fowler i PoEAA runt precis detta resonemang).
Att det finns en identitet i domänen, här orderid, är en dessutom en
viktig observation, då det ger tydlig hjälp i att sortera ut
entiteterna från värdeobjekten.
/Patrik
2010/11/4 Dan Bergh Johnsson <dan.bergh...@gmail.com>:
>
>
> 4 nov 2010 kl. 10.13 skrev Jonas Andersson <jona...@gmail.com>:
>
>> I praktiken har jag alltid använt en UUID generator. Se ovan. Och jag
>> skiljer mellan id'n för datanbaser och för människor. Exempelvis order-id är
>> för människor, och kan därför sättas när ordern är bekräftad
>>
>>
>> Det känns inte riktigt rätt för mig, en orders identet bestäms ju då inte
>> längre av orderid, vilket jag tycker att den borde (Å andra sidan är jag
>> fortfarande jag, oavsett vad mitt personnr är). Måste fundera mer på det.
>
> Jag brukar tänka på det som att orderid är ett verksamhetsattribut, vilket
> som helst. Sedan finns det attribut eller kombinationer av attribut som
> unikt pekar ut (högst) en entitet - i vissa .NET-kretsar har jag hört sådana
> uppsättningar kallas "determinanter".
>
>> Instinktivt ogillar jag också att en Entity innehåller saker av "rent
>> teknisk" natur, vilket ju UUID blir - Ordern blir inte lika "ren". Men det
>> löser onekligen upp beroendet mellan Factory och EntityManager.
>
> Egentligen ät uuid bara ett implementationstrick. Tänk att vi hade en
> oändlig minnes-heap på en krashsäker dator som aldrig behövde startas om. Då
> skulle varje objekt identifieras av den minnesadress den låg på och inga
> uuid skulle behövas. Däremot skulle en order fortfarande ha sitt
> verksamhetsmässiga orderid.
>
> Nu har vi ingen sådan heap utan måste spara ner våra objekt i diverse
> persistensmekanismer. Då är uuid bara ett trick för att spara och återskapa
> objektet - egentligen bara en "minnesadress" i det oändliga
> persistensminnet.
>
> När jag tänker på det sättet känns det inte så stötande att det finns ett
> "tekniskt" attribut i en entitetsimplementation. Åtminstone inte mer
> stötande än att en service av tekniska skäl skulle kunna hålla en Connection
> eller Socket öppen under lite längre tid.
>
> Dan
>
Dan
4 nov 2010 kl. 20.23 skrev Patrik Fredriksson <patrik.fr...@citerus.se
>:
> Om du vill göra ett inlägg i den här gruppen skickar du e-post till dddsverige@googlegroups.
> com.
> Om du vill sluta prenumerera på den här gruppen skickar du e-post ti
> ll dddsverige+...@googlegroups.com.
Alla egna entititesklasser ärver från basklassen Entity som har överlagrar funktionerna Equals och GetHashCode (dessa funktioner är viktiga för NHibernate (som är OR-ramverket som som Sharp Architecture använder)
Equals och GetHashCode baseras på de properties som är markerade med "Domain Signature" attributet
Entity-klassen innehåller också propertyn Id som är en integer och är objektets tekniska id.
(Om man behöver jobba med annat än integer som teknisk nyckel finns en annan klass att ärva ifrån)
Exempel på användning
På klassen Person sätter man DomainSignature-attributet på personnummer propertyn
Detta gör att du kan skriva personA.Equals(personB) och få svaret true om instanserna har samma personnummer.
För valueobjects finns basklassen ValueObject där du du inte kan sätta DomainSignature eftersom alla egenskaper på ett sådant objekt avgör om det är likadant som ett annat
/Mikael Egnér
-----Ursprungligt meddelande-----
Från: dddsv...@googlegroups.com [mailto:dddsv...@googlegroups.com] För Dan Bergh Johnsson
Skickat: den 4 november 2010 22:24
Till: dddsv...@googlegroups.com
Kopia: dddsv...@googlegroups.com
Ämne: Re: DDD i java: Använda EntityManager för att skapa ID i IdentityFactory
Dan
--
Det här meddelandet skickas till dig eftersom du prenumererar på gruppen DDD Sverige i Google Groups.
Om du vill göra ett inlägg i den här gruppen skickar du e-post till dddsv...@googlegroups.com.
Detta verkar g�ra antagandet att tv� entiteter som �r dom�n-m�ssigt
identiska har olika tekniska id'n. Korrekt? Hur kan det komma sig att
det finns tv� entiteter som representerar samma dom�nobjekt? Varf�r inte
bara j�mf�ra p� id't?
/Rickard
Dan
5 nov 2010 kl. 02.08 skrev Rickard Öberg <rickar...@gmail.com>:
> On 2010-11-05 06.21, Mikael Egnér wrote:
>> I Sharp Architecture (ramverk för .Net) sätter man ett attribut
>> "Domain Signature" på de properties som unikt identifierar ett obj
>> ekt
>> verksamhetsmässigt.
>>
>> Alla egna entititesklasser ärver från basklassen Entity som har
>> överlagrar funktionerna Equals och GetHashCode (dessa funktioner är
>> viktiga för NHibernate (som är OR-ramverket som som Sharp
>> Architecture använder) Equals och GetHashCode baseras på de
>> properties som är markerade med "Domain Signature" attributet
>>
>> Entity-klassen innehåller också propertyn Id som är en integer och
>> är
>> objektets tekniska id. (Om man behöver jobba med annat än integer
>> som
>> teknisk nyckel finns en annan klass att ärva ifrån)
>>
>> Exempel på användning På klassen Person sätter man
>> DomainSignature-attributet på personnummer propertyn
>>
>> Detta gör att du kan skriva personA.Equals(personB) och få svaret
>> true om instanserna har samma personnummer.
>
> Detta verkar göra antagandet att två entiteter som är domän-
> mässigt identiska har olika tekniska id'n. Korrekt? Hur kan det komm
> a sig att det finns två entiteter som representerar samma domänobjek
> t? Varför inte bara jämföra på id't?
>
> /Rickard
> Ofta ser man därför kod som ser ut så här (eller snarlikt):
>
> Person p = new Person(...); // utan personnummer
> p.makePartOf(folksamling);
> personRepository.save(p);
>
> Mycket kladdigare. Vad är personRepository för något?, undrar min
> domänexpert.
Fast det där är kod som finns där av tekniska skäl och inte något som domänexperten skall behöva se? Anledningen att du ofta ser sådan kod är att folk av någon anledning verkar ha lite svårt att skilja på vad och hur (som inte skall vara på samma ställe). Jag tror det beror på att när vi skriver koden tänker vi alltför lätt på hur man gör en sak, och bryter ned det steg för steg just på den platsen vi råkar komma på "att" vi vill göra något.
Vad vill jag göra? Lägga till personen i folksamlingen.
Hur gör jag det? Skapa ny instans, makePartOf o.s.v.
Av många skäl är det en god idé att hur-koden ligger i en annan metod än där vad-koden (d.v.s. intentionen, den som domänexperten dessutom är intresserad av) är. "Vad" blir bra metodanrop och "hur" passar ofta som små, fina, fokuserade metoder.
Om domänexperten behöver se repot så hade jag gärna döpt det till "persons" helt enkelt. Eller kanske även om de inte behöver se det.
Mvh
Niclas
---
http://niclasnilsson.se
http://twitter.com/niclasnilsson
On 2010-11-05 06.21, Mikael Egnér wrote:
I Sharp Architecture (ramverk för .Net) sätter man ett attribut
"Domain Signature" på de properties som unikt identifierar ett objekt
verksamhetsmässigt.
Alla egna entititesklasser ärver från basklassen Entity som har
överlagrar funktionerna Equals och GetHashCode (dessa funktioner är
viktiga för NHibernate (som är OR-ramverket som som Sharp
Architecture använder) Equals och GetHashCode baseras på de
properties som är markerade med "Domain Signature" attributet
Entity-klassen innehåller också propertyn Id som är en integer och är
objektets tekniska id. (Om man behöver jobba med annat än integer som
teknisk nyckel finns en annan klass att ärva ifrån)
Exempel på användning På klassen Person sätter man
DomainSignature-attributet på personnummer propertyn
Detta gör att du kan skriva personA.Equals(personB) och få svaret
true om instanserna har samma personnummer.
Detta verkar göra antagandet att två entiteter som är domän-mässigt identiska har olika tekniska id'n. Korrekt? Hur kan det komma sig att det finns två entiteter som representerar samma domänobjekt? Varför inte bara jämföra på id't?
/Rickard