Om man ska försöka följa "Domain Driven Design" (DDD) ska tex Customer klassen i princip enbart ha fältdeklarationer, egenskaper och konstruktorer, dvs förekomsten av metoder i klassen/entiteten är ett undantag. Om så är fallet var ska man då lägga metoderna om inte i entiteten? Eller har jag missförstått det helt? :) Nej du har förstått rätt. I vilka fall lägger man en metod i en entitet? För att sätta defaultvärden? Validering? Eller gör man det aldrig? Är detta verkligen korrekt? Jag vet inte vilken bok du läst. Men Eric Evans som är DDD's fader förespråkar modellen med respos, services och factories. Där finns självklart metoder som passar in din domänmodell (tex customer.Orders.GetMostExpensiveOrder()) men poängen är att du försöker skilja på olika "concerns" i så stor utsträckning som möjligt. Det innebär tex att domänen under inga omständigheter kommunicerar med infrastrukturen (DAL, O/R) och att den så länge det går hålls skiljd från delar som den vanligtvis inte ska ha tillgång till. Dessutom skall Domänen koncentrera sig på att representera Domänen. Dvs saker som används till att stödja applikationen och inte existerar som ett begrepp i den verksamhet man skall stödja, passar inte i domänmodellen. Vi har nog läst samma bok. Jag var nog otydlig. Jag tror jag förstår nästan hur du menar. Om vi tänker oss en klass som heter Order är det acceptabelt att i den ha en metod som hämtar orderraderna eller skulle du placera den metoden någon annanstans? Om inte det skulle vara acceptabelt och t.o.m. rekommenderat, kan jag inte se DDD som en verkligt objektorienterad metodik, eftersom entiteterna inte skulle bli mer än enkla strukturer à la C. I C# använder du inte metoder för att hämta orderrader, utan du har properties. Tillägg i stamtlet :-) "Som patrik säger så skall inte entiteter prata mot db, att prata mot db är inte i DDD direkt Rockard.. >>Ex kan en människa spara sig själv? Kan en Order ladda in sig själv? Order.Load(); Jag kan absolut se fördelar med DDD men jag ser även fördelar med Rickards tänk. Men underhållet och vidareutveckling över tid blir väldigt mycket enklare 1. Angående "kan en människa spara sig själv? Kan en Order ladda in sig själv?": Sant Jag uppfattar Customer i Customer.GetData(1) som en klass, inte ett objekt. För mig känns det lika naturligt med Jo men då pratar du associasioner eller aggregat som en repository normalt laddar in o skapar ditt släktträd... Jag vill också spy av Customers[0].GetByID(3), där Customers är en kollektion av Customer-objekt. anledningen till att man inte har statiska metoder för att läsa objekt är att men kanske vill ha en egen arbetskopia av objektet. Skulle man inte kunna göra samma sak med en statisk metod? vilket context skulle den statiska metoden binda ditt objekt till då? Ungefär så här borde väl gå bra public static Customer Create(Context myContext, string Namn, ......) Jag tycker att hela idén med att relatera arkitektur mot verkligheten är ganska naiv .. @Roger. Rickard... Från http://en.wikipedia.org/wiki/Object-oriented_programming#Matching_real_world: Man kan ju tolka texten där på helt olika sätt... Du får ursäkta, men det där inlägget kändes litet rörigt. Jag förstod inte vad du försökte säga. Det finns flera anledningar varför man undviker save i sina entiteter: Roger. <b>entiteternas uppgift i en applikation är att hålla data</b> Struktar hamnar på stacken och klasserna är ref typer och hamnar på heapen. I C kan både strukturer och objekt placeras på såväl stack som heap. Går inte det i .Net? Nej det går inte utan de har varsin plats. Eller jo, du kan "boxa" en strukt och lägga den på heapen. Men du kan inte ta en klass och få den att ligga på stacken. Det är i f-ö i princip den enda skillnaden mellan de båda. Strukt har lite mindre OOP funktionalitet än en klass också, men i övrigt är de samma. Johan Normén: Oj vilken sågning, hehe ;) Nejnej, lägg inte ner diskussionen, detta är mycket intressant att höra många olika åsikter. Min OR/Mapper är endast skriven utefter våra egna behov. Detta betyder nödvändigtvis inte att det är 100% optimalt, det går jag med på. Det finns många olika arkitekturer därute, alla med sina för och nackdelar. Jag förstår dina argument och håller faktiskt med på ett antal punkter. Rockard... Jag är inte så insatt i DDD men har köpt en bok där jag skall läsa lite om det, men jag har ett par frågor. Accelerate() <b>Jag läste en bok en gång om Objekt Thinking, författern sa där att all properties borde ha sitt eget event. Så fort en prop (attribut) ändrades skulle alltid ett event ändras.</b> Johan: Jepp! Intressant diskussion detta .. skulle vara lite lättare att fortsätta om man kan måla lite på whiteboard och samtidigt diskutera för och nackdelar, men lite svårt att skriva alla sina argument och lite tidsödande .. Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
DDD definerar andra platser att lägga olika typer av funktioner, som Factories, Repositories och Servies tex.Sv:Inga metoder i entiteten enligt DDD?
Sv:Inga metoder i entiteten enligt DDD?
För mig är just DDD att man placerar metoder som tillhör klassen, just i den egna klassen. Titta tex på time and money biblioteken som är gjorda av de som är skrivit boken. Här finns massvis med metoder som skall ligga i klassen. Sen kommer man att hitta metoder som inte går att placera i en entity, utan man får placera den i en egen klass, vilket då blir en service klass.
Att strippa klasserna helt på metoder å flytta ut dessa till services osv, förstör hela konceptet, då är man tillbaka till Table Module möntret. (http://www.martinfowler.com/eaaCatalog/tableModule.html).
Vilket iofs fungerar bra, men då är det inte DDD längre i mina ögon. Sv: Inga metoder i entiteten enligt DDD?
Det du föreslår, /är/ table module. Dvs att varje entitet har en klass som innehåller alla funktioner.Sv:Inga metoder i entiteten enligt DDD?
Ingenstans i den texten som jag skrev säger jag att man inte skall använda repos, services eller factories. Jag skrev också att man skall endast placera metoder som tillhör klassen i denna. Inte att man tex, man skall ha metoder för att spara objeket osv. Och precis som du skriver så skall domänobjektet endast represenera domänen, inte något annat. Det kommer det att göra om du placerar "rätt" metoder i det och detta är en konst som tar lång tid å lära sig. Hur du får detta till att vara table module vet jag inte.
När jag läste ditt svar så fick jag intrycket att du inte alls ville ha några metoder i domänobjektet, utan endast setter och getters för data, dvs i princip rena dto objekt. Sen skulle beteendet för objekten styras av services. Men det är möjligt att jag missförstod dig. Men jag kanske förstod dig fel.Sv: Inga metoder i entiteten enligt DDD?
Poängen är att om jag har metoder på Domänobjekten så får de bara använda sig av domänobjektet och dess hierarki, den får tex inte ropa ner till databasen för att ta reda på information om andra domänobjekt.Sv:Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
Sv:Inga metoder i entiteten enligt DDD?
Dvs Order.OrderLines (För Per Person som fortfarande jobbar med omogna ( ;) ) språk så skulle det innebär att det ser ut så här : Order.getOrderLines, vilket gör i princip samma sak).
Skillnaden är att getORderlines (eller OrderLines proppen) inte skall jobba mot ngn databas. Det skall inte domänmodellen hålla på med utan det är en annan "concern", infrastruktur separeras bort.Sv: Inga metoder i entiteten enligt DDD?
Entitets klasser i DDD skall ha affärslogik som till hör dess klass. Som Order
TotalAmount har logik som rälnar ut TotalAmount av alla OrderLines Artiklar typ.
Som patrik säger så skall inte entiteter prata mot db, att prata mot db är inte i DDD direkt
bussines logik heller vilkat Domänbiten just handlar om.
Repositories används för att typ göra en backup på sina objekst state...
En order med OrderLines har sitt tillstånd tyvärr existerar ju inte stöm o minne i all evighet därav nyttjar man ex OrderRepositories.Save(order) för att i princip göra en säkerhetskopia av sitt objekt...
I kort adrag :-)
Servcie klasser är klasser som inte är aggregat roots, eller entiteter, dvs en GasStation klass som endast har i uppgift att tanka en bil med bränsle är en service klass. gasStation.Fill(car,diesel)
Men skulle gasStation ha aggregats eller liknande kopplade på sig så som address m.m. blir dert helt plötsligt en enitet...
Så beräkningar, soteringar etc allt som tillhör äffärslogiken placeras i sina eniteter samt service klasser.
Data som måste lagras och hämtas och uppdateras skall gå via Respositories klasser.
Rätt enkelt egentligen. Sv:Inga metoder i entiteten enligt DDD?
bussines logik heller vilkat Domänbiten just handlar om. "
Varför? Vad vinner man på detta förutom att man följer DDD standarden ?
Vi har kodat ett generatorverktyg som gör allt i DALväg åt oss, samt en stor mängd features.
Men entitetklasserna har sina egna .Update, .Delete funktioner förutom sina properties. Det betyder då alltså att de även blir serviceklasser? Listklasserna har funktioner som t.ex .GetFilteredList, .UpdateAll, .DeleteAll, det lagras en del properties där med som t.ex connectionstring.
Jag ser att ni är DDD-fan många här, men jag ser inget att förlora på att ha en egenutvecklad arkitektur.
När man serialiserar, så är det väl endast state-datat man serialiserar?, själva logiken är ju där den är.Sv: Inga metoder i entiteten enligt DDD?
DDD är mer en spegling av verkligeheten är kod för en dator. Om man nu kan säga så.
Ex kan en människa spara sig själv? Kan en Order ladda in sig själv? Order.Load();
Load vad? order är en entitet... en människa kan inte ladda in kunskap utan att ta det från någon stans, ex läsa en bok. en bok ahr sidor, någon skriver texten på sidorna inte är det boken själv. etc...
Ett glas fyller inte sig själv med vatten, någon fyller glaset med vatten. Glas.Fill() hum...
glas = GlasRepository.GetGlasWithWater(); eller en service. vattenKran.Fill(glas);
En pärm entitet kan inte fylla sig själv med papper, man sätter i papper till den o någon har i uppgift att göra detta, en service eller ett repository.
Man separerar även DataAccess logik från sina verklgia domän objekt till repostiories för att ha ett enklare lager att göra ev justeringar i om någon behöver ändras på något sätt.
ex order.Load() <--- nu blir order hårdkopplad med DataAccesslogik. Dvs inte den löskoppling och single responsibility principle en order bör ha... Sv:Inga metoder i entiteten enligt DDD?
Person baby = SomeGuy.MakeBabyWith(someGal)
måste väl vara helt ok enligt den teorin då? ;-)Sv:Inga metoder i entiteten enligt DDD?
Objektorientering uppfanns ju för att det skulle bli enklare för människor att programmera.
DDD borde vara en förlängning av detta tänk. Men man kan fråga sig vilket som är enklast..
1.
Customer.GetData(1)
2.
CustomerObj = CustomerRepository.GetData(1)
Som jag ser det är case 1 mer strikt oop eftersom allt som har med Customer att göra återfinns i klassen Customer. När/Om man ritar klassdiagram innan man kodar så är ju detta ett sätt att begripa verkligheten på. Så enkelt som möjligt. Då ritar man Customer och stoppar in det som har med Customer att göra där. Sedan implementerar man Customer... Ofta får man datamodellen på köpet. Med DDD kommer ju antalet klasser i projektetet lite grovt att fördubblas till antalet. Det kanske blir bättre i längden men det blev ju inte en förenkling av problemet.. Speciellt inte när abstraktionen ökar och man börjar använda begrepp som Repository, Factory osv. Det blev til slut inte en förenkling av verkligheten, snarare en problematisering.. :)
Ett klassiskt citat:
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup. Sv: Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
Customer.GetData(1)
2.
CustomerObj = CustomerRepository.GetData(1)
För det första tycker jag att 1an är lite klurig. vad gör man egentligen Customer = Customer.GetData(1);
dvs man ber en kund att ge en annan kund?
Eller är 1. customer en tomt objekt där GetData(1) fyller dess inre properites? ja man hör själv lite att de tlåter lite dumt. Fyller sina innre properties eller att en kund ger en kund ;-)
Jag tycker dock det förvirrar då det dödar verkligheten lite.
Alternativ 2 kräver dock en extra klass men denna klass har en enda uppgift i hela din domän dvs datalagra ens entitets objekt. Kommer en property till i sin enitet lägger man till den o ser till så reposen hanterar detta. Vem vet kanske denna extra property måste hämtas från en annan datakälla än övriga properties då har du den logiken på ett o samma ställe i dina trepostirories. Du vet i ditt projekt vem som snavarar för vad. Alt 1 skulle bara ställe till det med problem då Custrumer inte bara är en Customer utan helt plötsligt en datalagrare. Lite mysko verklighetsanpassning tycker jag...
Men smaken är som baken. DDD är ingen lag, det är tycke o smak över en bra struktur... Som för mig fungerar bra mot verkligheten i många lägen...
Mvh JohanSv:Inga metoder i entiteten enligt DDD?
Detta är ett mycket populärt synsätt i LISP-världen. Data är kod, kod är data. Loggen är data, men den är också kod, och det finns inga skäl till att den inte skulle skriva sig själv. I och med att LISP i allmänhet inte är direkt förknippat med OO är det inte strikt relevant i sammanhanget, men jag tycker det är en intressant infallsvinkel.
Har en bra länk, men tyvärr verkar servern nere. Postar den här om servern skulle vakna upp igen.Sv: Inga metoder i entiteten enligt DDD?
men tänkt på att "skriva kod som en maskin kan förstå kan vem som men att skriva kod som en människa skall först" är inte alltid lika enkelt... Där av tycker jag att det är bra att ha det så verkligt nära världen som möjligt... Se matrix ;-)
Sedan handlar det om så mkt mer, löskoppling, open close principel, singe responability principle, tdd, förvaltning, uppgradering etc... det skall gå fort, det skall va enkelt det etc... vissa modeller gör det enklare speciellt tack vare ökad löskoppling. dvs ha egna klasser som har i uppgift att arbeta med persist data m.m. och andra som egna levande entiteter med affärslogik...
En entitet kan även leva i UI lagret, känns lite dumt att ha databaskod i en sådan klass... Det är lite som att kasta datalagret upp i UIt...
mvh JohanSv:Inga metoder i entiteten enligt DDD?
Customer customer = Customer.FindById(1);
som med
Customer customer = CustomerRepository.FindById(1);
<b>man ber en kund att ge en annan kund?</b>
Det behöver väl inte vara helt osannolikt, om än inte så vanligt? Håller man på med ett system för släktforskning, tycker jag att en person i systemet gott kan tillhandahålla sina föräldrar, syskon och barn, lika väl som sitt namn. I ett affärssystem kanske man har ett värvningssystem, där kunder kan värva nya kunder. I så fall kan ett kundobjekt tillhandahålla både den som värvat honom och vilka kunder han själv har värvat.Sv: Inga metoder i entiteten enligt DDD?
Customer.Person <--- Person entitet som lagts till när du hämtade en Customer. samma med
Customer.Address
Allt handlar om att Löskoppla beroenden, det gör inte du i ditt fall. Och just hårdkopplade beroenden kan ställa till med bekymmer... i ditt fall med Repository så säger den om man skall beskrtiva koden i ord...
Hämta en kund baserat på id från dess storage.
I första fallet. kund hämta kund med id...
Alltså jag säger inte att ditt fall är fel, men jag skulle aldrig göra så för i min värld har jag redan gjort så och det trasslade bara till det då allt blev så hårdkopplat... jag hade ingen direkt återanvändning av dessa objekt i mitt UI eller som transportobjekt mellan remote access då de hade bindning till dataccess komponenter m.m.
Om jag vill populera en ListBox med kunder vill jag ju inte att mina DataItems som jag bimnder dvs Customer skall ha mer än en kunds uppgift och associasioner. Att binda en tung klass som har logik som här hemma någon annan stans, är för mig inte ens tänkbart. Tänk dig en lista på Customer
Customers[0].GetByID(3) ??? ush... nä... inte min smak... men dock customers[0].Address eller .Person hade gått bra... men dessa är då aggregat eller value objects...
Det viktiga när man skriver kod är egentligen att andra förstår och att den är lätt att underhålla. kom ihåg att man oftast skriver kod för andra inte för sig själv...
Mvh JohanSv:Inga metoder i entiteten enligt DDD?
Men om GetById() är en statisk metod i klassen Customer och man skriver Customer::GetById(3) för att få tag på kunden med Id=3, är det betydligt mer korrekt OOP.Sv: Inga metoder i entiteten enligt DDD?
säg att vi har en webbsajt , om alla skulle jobba mot exakt samma instans så finns risken att någon ändrar på något medans andra använder objektet, + div andra trådningsproblem.
därför gör i princip alla mappers så att dina objekt blir bundna till ett context/session/workspace eller vad man nu vill kalla det.
då kan två personer samtidigt läsa kund 123 fast i olika contexts, det blir alltså två olika instanser.
jag kan jobba med mina egna instanser utan att behöva oroa mig över trådlåsningar och concurrency.
därför är repositories/factories praktiska.
de kan binda dina objekt till ett visst context direkt.
tex:
Customer cust = MyContext.CreateObject<customer>();//context binder objektet till sig själv
eller
Customer cust = MyContext.GetObject<customer>(123); //context binder objektet till sig själv
dessutom så är statiska metoder inte världsklass när man börjar blanda in arv bland objekten.Sv:Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
om man antar att tex en asp.net session bara är intresserad av att ha ett enda context så sure, eller att du har ett context per tråd eller liknande.
men det är inte helt ovanligt att man vill ha flera contexts i samma tråd/session, tex om den ena contexten används för att akrivt skriva data medans en annan kanske används för att hålla objekt som redigeras via ett gui, så att du kan avbryta redigeringar.
det finns flera andra fördelar också, tex så kan man committa hela sitt context och då spara alla förändringar, istället för att anropa någon form av "save" metod på alla objekt.Sv:Inga metoder i entiteten enligt DDD?
<code>
public class Customer
{
private Customer(){}
public static Customer Create(Context myContext, string Namn, ......)
{
//Skapa ett nytt Customer-objekt och initera properties.
// koppla det till angiven context och returnera objektet.
}
}
</code>
och liknande metod för t.ex GetById etc.Sv: Inga metoder i entiteten enligt DDD?
ja det går absolut.
men vad vann du på det då?
då får du vissa operationer i context och vissa som statiska metoder i entiteterna.
själv tycker jag single responsibillity och separation of concerns är bra koncept.
då vet jag tex att mitt context/whatever sköter kommunikation med db, medans entiteterna agerar datahållare.
med ditt förslag så blir entiteten både datahållare och ansvarar för skapande och initering av objekt.
men självklart går det att göra så, men personligen tycker jag att det är lättare att underhålla om jag vet att vissa klasser sköter vissa saker.
dessutom blir det lättare att unittesta om ditt factory går att ersätta med mock objekt / fakes.
medans det är omöjligt att ersätta anrop till dina statiska metoder i ett testprojekt.Sv:Inga metoder i entiteten enligt DDD?
Det viktiga i sammanhanget är väl ändå hur effektiv arkitekturen blir, hur det passar
ändamålet, hur lättförståeligt det är. Att det funkar som i verkligheten behöver inte
betyda att det är optimalt även om man vill. (ex den nya borgerliga regeringen)
För mig är det logiskt att man skapar ett skelett av en människa, och sen får skelettet
att "ladda sig själv" med muskler, ådror och blod. Den människan kan sen dö när den vill,
istället för att låta "människofabriken" döda människan.
Sen har vi en "människo-fabrik" (lista på MänniskoItem objekt). Och den kan OCKSÅ döda
sina tillhörande människor, eller filtrera dem, whatever.
Då behöver jag inte båda klasserna för att göra något, men jag kan om jag vill.
UI har inget med dessa klasser att göra. Basklasser med DALåtkomst, Partialklasser med
businessrules. Så, separerat och fint !
Sen när ni lämnat hieroglyferna :) som c# kan man enkelt uttrycka sig t.ex:
<code>
'ny och save
itm = New dbobj.clsUsers_Item(strConn)
itm.UserId = Guid.NewGuid
itm.UserName = Me.TextBox2.Text
itm.Update()
'eller ladda och delete
itm.LoadByPrimaryKey(1)
itm.Delete()
'eller ladda en sorterad lista och delete
Dim Users As New dbobj.clsUsers_List(strConn)
Users = Users.FilteredList("UserName LIKE '%rickard%'"
Users.DeleteAll
'eller bind nåt
Me.GridView1.Datasource = Users
</code>
Sen har vi så många features med vår kodgenerator att jag inte kan berätta dem för då
måste jag tysta ner er allihop sen :)Sv:Inga metoder i entiteten enligt DDD?
Jag sa inte att jag vann något på det, jag svarade bara på din tidigare fråga "vilket context skulle den statiska metoden binda ditt objekt till då?
".
Själv gör jag det helst på DDD-sättet om jag inte jobbar med t ex Ideablades DevForce. (http://www.ideablade.com) som jag tycker fungerar bra i många fall.Sv: Inga metoder i entiteten enligt DDD?
Hum... Så här ligger det till... Man skall helst skriva kod som männsikan förstår. En människa förstår oftast logiken med hur världen fungerar (se matrix ;-) )...
Att ett skelett kan skapa muskler o bla bla... är lite avigt hur det egentligen går till.
Vi ha rju sedan olika abstraktionsnivåer...
Skulle man skapa en människa kan det ske på lite olika sätt. Antingen via ett uppslag.
Eller att man manuellt anger hur en människa skall vara via formulär som i sin tur sedan faktiskt sparas för uppslag. Om människan enligt systemkrav inte finns i ett hus eller hos mamma så lever troligen människan i någon storage av något slag. dvs Repositoryn eller DalUser eller hur man vill namnge dem.
En männsika kan sedan att associasioner ögon, hjärta skelett m.m. vilket storage har i uppgift att koppla till en eller en factory i uppgift att bygga ut.
Sådan kod blir automatsikt enklare att förstå sig på då den är skriver för människan och inte för datorn i sig... Dvs alla kan skriva kod en maskin förstår men inte alla som en människa kan tolka.
Du har princip din repos här: itm = New dbobj.clsUsers_Item(strConn)
dock borde även denna updatera om man skall följa ett konsist mönster. Varför hämta med ett DAL objekt och sedan ge objektet tillstånd att spara sig själv?
Varför ha datalogik i två klasser när du kan ha det i en som dess hantering faktiskt hör hemma i?
itm = New dbobj.clsUsers_Item(strConn)
itm.UserId = Guid.NewGuid
itm.UserName = Me.TextBox2.Text
itm.Update()
så här skulle jag tolka denna koden.
man hämtar en användare baserat på en connectionsträng??? skumt.. men jaja.
Sedan sätter man dess värden, vem som gör det kan ju vara mamma i detta fall eller en factory.
Sedan updaterar man dess värden, dvs de lagsras i min itm...
men sen skulle jag klia mig i huvudet för jag fattar inte när jag läser koden hur denna person sparas, jag kan bara se hur denna skapas utifrån annat objekt.
Koding horror för mig...
Me.GridView1.Datasource = Users
Varför i hela världen skall ett DataItem i en Grid innehålla dataaccess logik? Varför kasta upp datalagerlogik till sitt UI för det är vad man gör när en enitiet kan spara sig själv. Det är för mig rätt obegripligt...
Jan:
public class Customer
{
private Customer(){}
public static Customer Create(Context myContext, string Namn, ......)
{
//Skapa ett nytt Customer-objekt och initera properties.
// koppla det till angiven context och returnera objektet.
}
}
Som ovan... Varför lägga dataaccesslogik i en entietet? Varför kan en kund skapa sig själv?
Ovh varför hårdkoppla detta berorende? varför tvinga UI att ha en entitet som har dataccess kod?
varför kräva att Customer vet vilken datakälla den skall hämta data från? Och om en Customer har en statisc create vem har då save? Static Save på sin entitet? Man tappar lite single responsibility principle här. eller rätt mkt. Vill man i ett UI skriva
customer.Update(); eller vill man att applicationslager o ens businesslager gör detta år en o kollar variant kontroller hantera fel m.m.?
Jag kan lova att man sparar både buggar, fel, tid och effiktiva uppdateringar o versionering genom att inte hårdkoppla dataaccess i sina entiteter utan låter ett helt eget objekt hantera detta åt en för sina entiteter....
Mvh JohanSv:Inga metoder i entiteten enligt DDD?
<info>
According to object-oriented principles, the verb in a program statement is always attached to the object, and the logic associated with a requirement is likewise handled in the object.[verification needed] The following are some examples of the ways by which a subject-oriented requirement is translated into object-oriented thinking:
* Subject-oriented: The Sales Application saves the Transaction
* Object-oriented: The Transaction saves itself upon receiving a message from the Sales Application
* Subject-oriented: The Sales Application prints the Receipt
* Object-oriented: The Receipt prints itself upon receiving a message from the Sales Application
</info>
Alltså, om man håller med om ovanstående, är user.save() mer objektorienterat än userStorage.save(user).Sv: Inga metoder i entiteten enligt DDD?
ex innom OOP finns ju moduler (paket,namespaces) etc...
Kvitto ex kan ha två saker.
KvittoHanterare och kvitto. Där kvitto är en informations klass efter OO info pattern.
Dvs en klass med attribut, Kvittohanteraren är den som hanterar kvitto infon, ex
skriver ut den, räknar om data för presentation m.m.
* Object-oriented: The Receipt prints itself upon receiving a message from the Sales Application
Reciept här kan mkt väl vara Applicatonslagrets objekt, det är OOP i andra lager med.
OOP är som det även står på den sida du angav att man orienterar sig mellan och med objekt som motsvarar dess identitet. Design patterns kan vara OOP patterns för att effektivisera sin modell,
Arv är ex ett pattern, polymorphism med, men de är så självklara så när man pratar design patterns har man i många fall tänkt singleton, composite etc... lite större mönster.
DDD är just en abstraktion av en massa, för att effektivsera löskoppla och få en enkel design av sina objekt.
DDD är inte kung, men sedan ajg arbeta med DDD än som innan så har det bara gett fördelar att låta storage klasser för mina entiteter hantera datacess. Vissa skäl har jag tidigare nämnt.
bla bla... Men man skall göra det som gör det bäst för en själv och för andra...
Mvh JohanSv:Inga metoder i entiteten enligt DDD?
Vill förtydliga att även om ett objekt tillhandahåller metoden save(), behöver inte det betyda att den kommunicerar direkt med databasen. Jag kan mycket väl acceptera att objektet använder ett annat objekt för detta:
<code>
class Object
{
void save() { ObjectStorage.store(this); }
}
</code>Sv: Inga metoder i entiteten enligt DDD?
1)
objekt pekar ofta ut andra objekt i sina properties och måste då insertas/uppdateras i db i en viss ordning. att sapara ett enskillt objekt går i princip bara om det håller primitiva properties.
därför är en context/workspace lösning smidigare då man kan låta den persista en hel graf av förändringar , dessutom i rätt ordning
Rent tekniskt så är det absolut möjligt att låta save i en klass anropa save på relaterade objekt ifall även de ändrats.
själv skulle jag uppleva det som otydligt om jag anropar save på ett objekt och flera andra sparas.
2)
entiteternas uppgift i en applikation är att hålla data
allt annat är smidigare att ha som externa tjänster.
tex , spara objekten , presentera objekten som html , transformera objekten till xml, binda objekten till en grid etc etc är tjänster som är lämpliga att lägga utanför objekten.
dvs det har ingen impact på existerande kod och det blir lätt att underhålla då entiteterna inte växer o växer för varje ny feature man hittar på
så det hela handlar inte alls om att vara så rätt oo som möjligt utan bara pragmatiskt praktiskt.
tusentals utvecklare har jobbat med ormapping och 99% av alla orm ramverk som skapas nu använder dessa regler för att de visat sig fungera bättre än att fluffatill objekten med massa extra kod.Sv:Inga metoder i entiteten enligt DDD?
Bra svarat... Sedan handlar det hela egentligen om smak o tycke...
sedan jag applicera DDD så blev allt mkt effektivare o enklare än när jag faktiskt från början
gjorde Order.Save att ens egna klasser hade en massa andra skumma tillstånd :-)
Även transaktionshanteringen underlättade för mig m.m. men det är ett annat kapitell.
Nu lägger jag ner detta. Jag vill inte säga använd DDD vill bara föklara hur jag ser på det hela...
arkitektur är mkt prat o teorier o smak o tycke... viktigast är egentligen
Flexibilitet och att man faktiskt skriver koden för andra o inte sig själv... Det är de mål jag har...
oavsett om man använder Order.Save eller OrderRepository.Save(order) :-)
mvh Johan - Over and out!!!Sv:Inga metoder i entiteten enligt DDD?
Varför öht använda klasser? Vanliga strukturer (à la C) borde väl räcka?Sv: Inga metoder i entiteten enligt DDD?
Att lagra stora datastrukturer på stacken är inte att rekomendera,Sv:Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
Sv:Inga metoder i entiteten enligt DDD?
Sv: Inga metoder i entiteten enligt DDD?
I vår syn är vår objektarkitektur helt logisk, och matchat mot verkligheten, jag kan inte förstå hur man kan hävda annat ..
Jag måste få ge min åsikt att det som kallas "real-world matching" kan ses från olika vinklar.
Vissa hävdar att Gud skapar, formar och dödar människan (gud är factory). Andra ser att människan skapas själv från celler, och via föda utvecklar och bygger sig själv, för att sedan bestämma när den vill dö eller dör av ålder, m.m.
Svarar på dina frågor (om vi ska utgå enligt synen på matchning mot verkligheten):
Varför lägga dataaccesslogik i en entietet? : Varför inte? Människan lever, växer, utvecklar muskler, blod, etc själv. Objekt kan likaså.
Varför kan en kund skapa sig själv? : Varför inte ? Samma som ovan..
Ovh varför hårdkoppla detta berorende? : Absolut inte hårdkopplat. Ex: CustomerList.LoadBySql("fname like 'AB'") annars skjuter man sig själv i foten ..
Varför tvinga UI att ha en entitet som har dataccess kod?: Finns alternativ i min factoryklass om man föredrar det.
Varför kräva att Customer vet vilken datakälla den skall hämta data från?: Det finns även i CustomerList om man föredrar det.
Och om en Customer har en statisc create vem har då save? Static Save på sin entitet? Man tappar lite single responsibility principle här. eller rätt mkt. : Alternativ som jag har är: CustomerList.UpdateAll (här finns både insert och update, även delete om varje Customer är "MarkedForDeletion")
customer.Update(); eller vill man att applicationslager o ens businesslager gör detta år en o kollar variant kontroller hantera fel m.m.? : Vi använder partialklasser där man kan kringgå det.
Jag kan lova att man sparar både buggar, fel, tid och effiktiva uppdateringar o versionering genom att inte hårdkoppla dataaccess i sina entiteter utan låter ett helt eget objekt hantera detta åt en för sina entiteter....: Det stämmer om man nu ska skriva allt själv. Men detta genereras, så det enda som krävs för mig är att uppdatera generatorn, och klicka på Generera om kod. Sv:Inga metoder i entiteten enligt DDD?
Jag läste en bok en gång om Objekt Thinking, författern sa där att all properties borde ha sitt eget event. Så fort en prop (attribut) ändrades skulle alltid ett event ändras.
Dvs en sådan modell låter lite som din gud vs cellskapande.
Jag vet inte vem som skapade vår moder om det var gud eller en cell.
Utgår vi från GUD så är factory rätt bra och enkelt. Utgår vi från cell så bör event sättet vara en bra lösning. Dvs om celen ändras så ändras en hel kedja med saker något är kopplat till cellen som i sin
tur borde justeras när cellen förändras m.m.
Så en kund som kan skapa sig själv borde då kunna leva själv ala The Matrix.
Kan en kund skapa sig själv (Cell tänket) och man ändras kundens namn så borde ett event triggas så alla kunder som känner till denna kund för meddelande om att kunden har nytt namn. Samma med Order som har en kund kopplad till sig etc... ;-)
Nä skoja nu... Jag började en gång bygga på ditt sätt User.Create() för att jag såg User som två saker.
Antingen en class som har ett ID eller oxå som ett objekt som kan ge mig en klass.
Jag tycker en sådan modell sedan blev lite svår läst och tung jämfört med en tunnare modell där man kopplar från mer... Jag vill bara ge möjlighet att skapa en användare på ett sätt och på rätt plats i min kod än att kunna skapa användare vart jag än var i min kod.
Måste då lägga till att jag skriver koden för andra och vill då hålla ett mönster OOD ex i flesta fall för att andra skall koda på samma sätt när de kanske tar över min kod.
Lätt hänt att saker och ting inte följer sitt möster för det ger för mkt åt utvecklaren...
Mvh JohanSv: Inga metoder i entiteten enligt DDD?
Får det inte finnas några metoder alls?
Rent logiskt tycker jag ju att det borde finnas det t.ex. det gamla hederliga Bil objektet med metoder som
Accelerate()
Stop()
TurnLeft().... osv.
Däremot skulle jag kunna tänka mig att man hade en CarFactory istället för Car.Load(), Save() och Update(), är jag ute och cyklar?
Alltså borde det inte finnas funktioner i objektet som arbetar mot den datan som objektet innehåller?Sv:Inga metoder i entiteten enligt DDD?
Stop()
TurnLeft().... osv.
finns :-)
Objekten skall ha metoder och properties.
Facotry skapar objekten åt dig om de är avancerade objekt typ behöver massa info via konstruktorn m.m. Annars nyttjas Repositories om det handlar om att ladda upp objektets information.
Ex kan det vara lite jobbigt att skriva:
Car car = new Car();
car.FramVänsterDäck = new Däck();
car.FramHögerDäck = new Däck();
car.Ratt = new Ratt();
...
Här är en CarFacotory utmärkt att ha...
Car car = CarFactory.Create();
Mvh JohanSv: Inga metoder i entiteten enligt DDD?
Något i stil med Mozillas implementation av JavaScript, där man kan lyssna efter ändringar i en property?
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object:watchSv: Inga metoder i entiteten enligt DDD?
Per, antingen via Johans car factory, men man skulle också kunna ha:
Dim car as new Car(<kanske-nån-parameter>)
Så körs konstruktorn på Car-objektet och sätter alla dess grundproperties istället för att manuellt göra det i kod varje gång.
ps; lite offtopic men vårt kodgeneratorprogram generar alla klasser åt mig samt ger mig partialklasser som jag kan hantera hur jag vill =), från början var det ett ganska lätt program men vi har jobbat hårt och det är nu väldigt komplext och hanterar även relationer, att skriva om allt skulle ta för lång tid för mig =) - men det skulle konkurrera kraftigt mot dagens populära or/mappers som t.ex Raptier, Codesmith etc! Men arkitekturen för generatorn är redan lagd som sagt, så det kanske är lite därför jag försvarar den extra mycket ... Hehe. Men smaken är som baken!