Jag är nyfiken på vad som är "best pratices" när man gör relationer mellan två objekt som tex kund och order. Vi antar att en kund har en orderkollektion och en order har en kund. Är nedanstående uppbyggnad sättet hur relationerna görs rent generellt eller finns det något bättre sätt? Jag undviker "bidirectional" så ofta det går för det kan leda till förstora entiteter och får många vägar att gå för att komma åt data. Min erfarenhet i stora projekt är att en entitet kan bli väldigt stor, och vi ska inte ha förstora entiteter, så då får vi välja andra vägar att lösa detta. När jag arbetade med B2B så ansåg vi inte att kunden skulle vara en behållare av order, utan order ska veta om kuden.. För om kunden ska vara behållare av order, då kan kunden även vara behållare av fakturor etc. Customer som entitet växer och kan bli "klumpig". Om du har en väldigt stor entitet så får du tänka mer på hur du ska ladda dess aggregat och value objects etc. Jag brukar köra med KISS och frågar min OrderRepository efter vilka orders en kund har, för att slippa stora eniteter. Jag tycker det där är en mycket intressant fråga, när jag tänker på det direkt utan att behöva tänka på lagring/databas osv, så känner jag att enligt domänen så har kunden faktiskt Ordrar kopplade till sig. Och för att slippa tänka / blanda in repositories och andra lager så hade det känts ganska bekvämt att kunna hämta ordrarna som kunden har kopplad till sig t.ex. Kan vara så att din domänmodell behöver ha Orders på Customer, och då ska du ha den där.. Jag försöker även tänka "Object Thinking" finns en bok om det som har just det namnet. Om jag själv är kunden så bär inte jag på alla mina Orders, utan någon annan har hand om dom, tex ett ordersystem. Sedan frågar jag efter dom.. Skulle jag bära på allt jag äger så skulle jag behöva vara en magic bag. Att fråga efter Orders för en specifik kund via en Repository är inte att tänka på databasen. En Repository gömmer "data accessen" och allt vad databas är.. Vi ska se Repository som en behållare av objekt, vi ska inte bry oss om hur vi materailiserar entiteterna eller vart vi hämtar dom etc. -> Fredrik "En annan sak som är JÄTTEviktig när vi arbetar med orders och fakturor etc, är att informationen ska inte ändras över tiden när väl ordern är skapad etc" hmm, det var ett annat sätt att tänka på :), ett ganska bra sätt tycker jag. (dvs att du inte bär runt på alla ordrar). @Krister: @Magnus Just när det gäller historik och kopplingar. "var har Kunden isåfall sina ordrar, skrivbordet?" Jag brukar inte skapa serviceklasser utan tycker att dom i många fall kan bli "mellanlager" i princip inte tillför något än att de bara skickar vidare förfrågningar och data. Det är sant att lazy load har sina begränsningar. Det som jag önskar och hoppas ska komma i framtiden är att OR-mappern eller EF kan själv avgöra vilken data som behövs vid varje specifikt metodanrop. Det borde inte vara så svårt att implementera detta med tex reflection efter kompileringen. @Krister: Jag fick för mig att Evans skrivit lite om modeller, där skriver han att ju fler associationer vi kan undvika desto bättre. Eller ja man skall ju inte ta bort de som verkligen bör ligga där, men man bör verkligen fråga sig om de ska ligga med. Så jag börjar nog vända mig åt att skippa att ha Orders listor på Customer om det nu inte är så att det är det ända i systemet en kund används till. Som jag ser det är det här en brist i de objektorienterade språken snarare än något annat. Det som finns är i praktiken pekare och listor av pekare; det finns inget stöd för mer generella associationer. Hade det funnits, hade man kunnat ha en situation där en "orders"-lista på en customer inte uppvisar de problemen ni pratar om. >Om vi antar att vi har ett exempel "Bil", "Person" och "Ägare"; då skulle man kunna definiera bil separat, Spännande fråga, just det där exemplet med bil och ägare känns ju som att det är ett skolexempel. Nu har jag inte läst Martins svar i detalj, men jag tror han har slagit huvet på spiken med vad jag pratar om. I mitt fall så ser jag Garage en samling/repository. Jo, jag förstår precis, min poäng är att det är lika meningsfullt att ha accessors från alla håll, men att det blir jävligt stökigt och error prone om man försöker göra det på riktigt. Att säga att vilket som är rätt är fråga om domänen känner jag mer som att ta ett problem i ett språk och lägga ansvaret på sig själv. Mmm, så har jag tänkt tidigare att ha accessors från alla håll, men jag vet inte riktigt om det är den bästa lösningen i alla fall. Allting blir ganska kopplat till varandra. Men jag kan vet inte vilken väg som är den rätta i detta fallet, tidigare har jag gillat referenser då jag gillat att "surfa" mellan mina objekt istället för att behöva anropa repositories eftersom jag tycker att det är mer objektorienterat att ha referenser istället för att gå emot repositories så fort en lista skall hämtas som har t.ex. med en person att göra. Jag vet inte om jag hänger med i det ni tagit upp men det som jag tycker är att om jag drar en association mellan två entiteter så ska man per automatik ha åtkomst åt båda hållen utan att behöva skapa en "bidirectional". För det är något lurt i att man ska behöva skapa en "bidirectional". Det är exakt det som är min poäng. Har egentligen inte tid med det, men det borde vara så att man som standard får eller kan få en bidirectional association, och att man kan avaktivera det vid behov. En bil har inte en ägare, en bil vet inte vem som äger den.. det är ett register som talar om vem som äger bilen ;) Men får vi ut information om bilen, så kan vi se vem som äger den, men det är eget bil objekt vi får ut, utan ett annat typ av objekt med information om bilen.. bara en tanke ;) <b>>En bil har inte en ägare, en bil vet inte vem som äger den.. </b> ">En bil har inte en ägare, en bil vet inte vem som äger den.. Jag tror du missar min poäng. Jag tycker också att man _borde_ utgå ifrån domänen. Låt oss ta ett annat exempel om du hänger upp dig på att en bil inte känner till sin ägare; företag och anställda, eller förälder och barn. Poängen är att det <b>kan</b> vara så att båda känner till varandra, och problemet är att vi då måste göra komplicerade implementationer för att beskriva det, och att det är löjligt. "Din domänmodell kommer påverkas av vad du arbetar i för språk." hmm, intressant, diskuterar vi oo så vill jag nog ändå påstå att man kan säga att en bil har en ägare även om en bil inte kan säga dig vem ägaren är i verkliga världen så tycker jag inte att den associationen är fel i många fall. Jag hade utan problem kunna rita upp "bilen har ägare relationen" i mitt UML diagram i många fall. (domänen måste inte följa verkligheten till pricka anser jag). Återigen - nej, domänmodellen "behöver" inte, och borde inte, styras av språket du använder. Vi är helt överrens om det. Det jag menar är att den trots allt gör det. Du har ett språk i bakhuvet, och det är utifrån det du gör din domänmodell. "Ubiquitous" är en illusion. Jag vet inte hur vi hamnade utanför OO-spåret, det finns enligt mig ingen anledning att göra en domänmodell om man inte kan eller vet vad OO är, ända anledningen till att göra en domänmodell i ett funktionellt språk skulle vara att få fram krav ur den men då måste man ju känna till vad ett objekt är samt relationer. Ja, nu pratade jag inte om funktionella språk utan om procedurella. "Nu är jag mycket dåligt insatt i DDD, men jag misstänker att det inte finns någon principiell orsak till att det måste vara ett av C++-oo-språken för att kunna använda metodologin, och av det lilla jag har sett av DDD, så kan jag inte se något som hindrar en från att göra samma sak i en procedurell miljö." Det verkar fortfarande inte som att min poäng går fram. Jag menar inte att det är lämpligt, jag säger att det är teoretiskt tänkbart. Och om det hade varit så, så hade du inte gjort samma domänmodell, inte sant? "Det verkar fortfarande inte som att min poäng går fram. Jag menar inte att det är lämpligt, jag säger att det är teoretiskt tänkbart." <b>>Man skall dock vara försiktig att tillämpa OO för hårt i modellen, eftersom den skall kunna förstås av folk som inte har någon anning om OO. Men oftas så kan folk relatera till OO så det brukar inte vara så svårt att förstå.</b> <b>Visst är det teoretiskt tänkbart, men återigen knappast praktiskt</b> "Vi kan ta det här testet istället: Om du gör en domänmodell, kommer du aldrig någonsin på tanken att "det kan vara ett event", och uttrycker dig annorlunda vad gäller events i själva modellen? " <b>>Kan du inte implementera en lösning på ett visst sätt för att verktygen hindrar dig ifrån det, så måste du ju anpassa domänmodellen till det, och finns det verktyg som gör att du kan implementera din domänmodell på ett bättre sätt, så bör du ju använda dessa verktyg.</b> "Eller menar du att DDD är olämpligt och opraktiskt om man inte har ett språk med stöd för OO?" "Kan det då inte vara så att du köper oo-modellen i C# rakt av, utan att ifrågasätta den? (Och med "du" så menar jag inte dig utan alla.) " Nej, om du kollar vad tråden handlade om från början - hur hanterar man kund/order-relationen - och mitt första inlägg; Intressant, vad bör det vara om inte en "futtig pekare"? Ja, det är ju upp till kompilatorimplementationen (precis som arv), men grundprincipen är att vi borde kunna definiera relationer mellan objekt. Nu har jag ganska liten vana av språkdesign; men om vi tänker oss en enkel 1-1-relation; låt säga att en person alltid äger exakt en bil, och vice versa, så skulle det i implementationen generera pekare åt båda håll. Niclas, jag tror att Niklas tänker på relationer i mer abstrakta, inte implementationstekniska, termer. En bra metodik borde man kunna använda likadant oavsett programmeringsspråk och den skall ge en lösning som genom språkberoende regler direkt kan mappas till en implementation i ett språk. Jag tycker Niklas J är inne på en väldigt intressant sak och det kan sammanfattas med att "bidirectional" ska förenklas. Man ska alltså inte behöva dra två pilar utan det ska räcka med en och där du via någon form av egenskap anger om åtkomst åt ett eller båda hållen. Skulle man få till det då har man verkligen utvecklat OO. Och helst inte bara birectional, utan en mer generell "relation", för att hantera 1-n, n-n och gärna skumma varianter som 7-n, och med godtycklig logik för vilka regler som finns. <b>Och helst inte bara birectional, utan en mer generell "relation", för att hantera 1-n, n-n och gärna skumma varianter som 7-n, och med godtycklig logik för vilka regler som finns.</b> Jag hade inte velat att en bidirectional "automatiskt" skulle dyka upp. I många fall är den referensen åt ena hållet helt onödig och kan göra din lösning mer komplex i och med att affärregler oftast måste verifieras vid relationerna, jag brukar försöka hålla ansvaret av sättandet av bidirectional relationer på ett av objekten. Om språket stödjer sådana relationer så skulle dock de affärsreglerna kunna ligga i relationen och inte i klassen som råkar ha en relation. Likaså borde man då rent teoretiskt kunna sätta upp någon konstruktion för vilka relationer som ska visas, tänker man t.ex. .NET så skulle man kunna begära att vid en 1:1-relation så skapas en property automatiskt på den ena klassen, på den andra förpassas propertyn in i en explicit "interfaceproperty", där man måste casta objektet till ett interface först. Eller något åt det hållet. (Ganska ogenomtänkt i skrivande stund, men jag ser inte det som ett problem med automagik på relationer/propertys) Oskar och Per verkar vara med på hur jag menar. Skönt att ha någon backning... =) -> Niclas P Jag har funderat lite och är inte grundfrågan lite OO vs SOA ? Njae, jag tycker nog det är fråga om huruvida OO är "fullständigt implementerat" eller inte. Anledningen till att jag drar paralleler mellan SOA och OO är att i en OO lösning tycker jag att Order.Customer osv är rätt men i en SOA lösning behöver det vara mer löskopplat för att fungera bra så där kanske det skall till en service för att koppla dom. -> Niclas P Orsaken till att jag ansåg att frågan handlade om var att jag tolkade huvudfrågan om man det var rätt att ha Customer och Orders relationerna. Litet inflik om SOA... :) Ola, kan du nämna ett lyckat SOA projekt? Pressen skriver bara om alla som misslyckats med det, jag tror iofs inte på SOA och kan förstå att det inte finns så många lyckade projekt för många vet inte hur de ska bygga en bra SOA lösning, eller jag kanske har fel? Men själva tanken är är god, om man lyckats med det ;) Att jämföra SOA med mappa SQL tabeller mot Objekt är helt befängt.. en tjänst är en tjänst, och den lika väl som många app internt använda sig av ORM. Det jag har gjort om till SOA har funkat bra.. Hmm, hur kom vi in på SOA och ORM? Nu har Niclas helt rätt, nu har vi spårat ur.. men vill förklara SOA Projekt.. ett projekt där SOA används som arkitektur.. Nodea har tex haft flera projekt i gång för att applicera SOA, jag antar att du vet vad projekt är ;) Kan skapa en helt annan tråd kring SOA, har iofs tidigare haft diskutioner kring detta på pellesoft.. så kanske ska dra igång den tråden igen :P Hmm, jag har funderat lite kring det där med relationer och sökt lite info om det. Det har inte med minne att göra huruvida du vill ha en koppling mellan alla typer, det har med underhåll och exakthet att göra. Som jag skrev i mitt inlägg så nämde jag att i större system så skall man kanske inte ha denna relationen. Nej jag missförstod nog inte, jag vill mena att principen även gäller mindre system. Av den simpla anledningen att de flesta system sällan har ambitionen att vara små särskilt länge. "Best pratices" för tex kund & order relationerna?
public class Customer
{
private IList _orders;
public IList<Order> Orders
{
get { return _orders; }
}
public class Order
{
public Customer Customer { get; set; }Sv: "Best pratices" för tex kund & order relationerna?
Order bär ofta på information om en kund, så på order skulle jag valt en egenskap som ger mig information om kunden.
OBS! Allt beror på domän modellen som vi tar fram med en domän expert!Sv:"Best pratices" för tex kund & order relationerna?
public IEnumerale<IOrder> Orders.... på kunden eftersom enligt domänen så har ju kunden ordrar.
Sedan vill man ju knappast ladda in alla ordrar för varje kund när man hämtar en lista med kunder, men det är en mer teknisk fråga dvs lazyloading som indirekt blir en ganska komplex lösning om det handlar om djupa objektgrafer, speciellt om man sedan blandar in olika typer av tjänster som t.ex. WebServices osv.
"bidirectional" - Gör att det kan börja bli komplext, dvs att sätter man Order.Customer = customer; så bör order lägga till sig själv i Customer.Orders, men här bör man nog låsa utvecklaren så att han inte kan sätta Order.Customer = customer; utan tvinga utvecklaren att lägga till ordern på kunden. Då kan man sedan direkt säga att det är kunden's Repository som ser till att spara kunden samt Ordern.
<Code>
public void AddOrder(Order order)
{
InnerOrderList.Add(order);
order.Customer = this;
}
</code>
Men jag håller med entiteten kan växa enormt, men jag vet inte riktigt om jag håller med att man ska ta bort Order's från Customer.Sv: "Best pratices" för tex kund & order relationerna?
En annan sak som är JÄTTEviktig när vi arbetar med orders och fakturor etc, är att informationen ska inte ändras över tiden när väl ordern är skapad etc. Tex om vi har customer.Orders så får vi till gång till kundens order, om vi byter namn på kunden, tex efternamn så får vi problem, för ordern som är skapad ska referera till kundens då varande namn, inte vad han heter just nu.
Se på detta:
customer.LastName = "New Name";
customer.Orders
Om kundens LastName va "Svensson" innan så ska vi inte få ut det order som tillhörde "Svensson" utan de som nu tillhör "New Name". Historiken måste sparas.. så kuden tar en annan form beroende på context. Customer på en Order är oftast immutable för att se till så vi inte kan ändra kundensinformation via order.Customer, utan vi måste tilldela en ny kund eller när ordern väl är skapad, ska vi inte kunna tilldela en ny kund.Sv:"Best pratices" för tex kund & order relationerna?
Det är intressanta synpunkter du tar upp! Dels det med att kunden inte går runt och bär på sina ordrar samt det att en specifik Customer-version bör vara kopplat till en viss specifik order.
En fundering som jag har är att istället för att använda ordersystem-konceptet varför inte använda olika interface på kundentiteten för att hantera tex property-komplexitet och på så sätt göra entiteten mer utvecklarvänlig?
Detta med prestanda kan man som sagt hantera med bland annat lazy load. Lazy load i kombination med interface hanterar på olika sätt detta med storleken på objektet. Storleken på kundentiteten utan interface kommer man dock inte ifrån. Eller?
Måste dra... :)Sv:"Best pratices" för tex kund & order relationerna?
Det där är rätt, även om jag anser att just det exempel som du hänvisar till är felaktigigt. För just att ändra efternamnet på en person bör inte ändra möjligheten att finna denna personens order. Det är ju knappast efternamnet på personen som är ihop kopplat med order, utan själva personen.
Så oberoende av vad jag ändrar på personen så börja alltid få denna personenens alla order, däremot så kan det finnas information som man vill ha kvar av just denna person vid leveranstillfället.
Ett praktexempel på detta är ju priset på en vara i en orderLine. Om vi ändrar priset på varan så vill vi ju knappast att priset som kunden beställt vara för skall ändras, där måste varanspris sparas ner på orderlinen. Sedan är det upp till olika projekt att bestämma vilken av infomationen som är viktig att spara vid order tillfället.
- MSv:"Best pratices" för tex kund & order relationerna?
Japp information om kunden måste sparas undan i ordern men det är inte så dumt att ordern känner till vilken kund i systemet som den ligger på. Men allt beror på krav osv som vanligt :).
Tror du missuppfattade mig jag relaterade inte repository till databas även om jag säkert skrev något som gjorde att man kunde anta att det var så :)Sv: "Best pratices" för tex kund & order relationerna?
Lazy Load har sina fördelar men ofta resulterar det i fler problem än vad det löser.. Så jag föredrar ofta eager loading. Du kan läsa lite om Lazy Load problemet här: http://weblogs.asp.net/aaguiar/archive/2004/10/06/Lazy-Loading-is-a-domain-problem.aspx
Vet inte exakt vad du tänker på när du går in på interface på kundentieten, men om det är vad jag tror så är jag rädd att det kan leda till att vi bryter mot Interface-Segregation Principle. För du menar att du har olika interface som kundentiteten implementerar, och sedan i din kod så använder du ett specifikt interface beroende på context? Eftersom en kund kan ta "olika" former inom olika context, så kommer även egenskaper kunna ha andra namn..Sv: "Best pratices" för tex kund & order relationerna?
"Det är ju knappast efternamnet på personen som är ihop kopplat med order, utan själva personen.", Om vi måste av historiska skäl spara order till en persons uppgifter, så nej, dom tillhör inte personen fast i verkligheten gör dom det. Detta är ett bevis på att vi kan inte skapa ett system som är en reflektion av verkligheten, för i verkligheten är det personen som har order, men i systemet med historik, så är det personens information som äger dom. Med andra ord borde inte Orders ligga som egenskap på Customer, utan vi borde fråga efter Orders baserat på en kundsuppgifter. MEN! OBS nu ett STORT MEN.. Det beror på modellen samt om historiken är viktig i vårt sammanhang. Fakturer finns det lag på.. just på orders, vet jag inte.. jag vet bara att i den B2B app jag va med och utvecklare, så var det viktigt att spara orderhistorik pga uppföljning etc.
Jag undviker vissa aggregat om inte domän experten säger något annat.. Sedan finner jag det mer logiskt att fråga efter Orders för en kund, än att kunden ska bära på den.. för om en kund kan ha Orders, då borde han/hon också ha Invoices, Agreements etc.. kunden kommer bli FET! ;)Sv:"Best pratices" för tex kund & order relationerna?
Även om man kan diskutera kopplingen mellan Customer och Order, så behöver ju inte kopplingen användas för att få fram Ordens kunduppgifter när Ordern väl gjordes
<code>
public class Order
{
public Customer Customer....
public Name CustomerName
public Address ShippingAddress
}
</code>
Men fortfarande det som du sa med att Kunden inte kan bära runt alla sina ordrar, om vi leker med tanken i en domänmodell, var har Kunden isåfall sina ordrar, skrivbordet? :D
Ne men man kan väl säga att kunden bär runt på sin identitet och om kunden identifierar sig så kan han få tag på sina tidigare Ordrar. Vad skulle objektet som Kunden identifierar sig emot kunna heta (om vi struntar i att kalla det för OrderRepsository / OrderService), hm tänker medans jag skriver OrderService är inte ett helt fel namn :), eftersom det bör vara en typ av service kunden använder när han i verkligheten frågar efter sina ordrar :D.Sv: "Best pratices" för tex kund & order relationerna?
Det intresanta är att kunden har inte sina orders, det vi kan få ut är en lista på orders via ett system eller på papper.. men själva ordern håller inte kunden i, sug på den :P
Respository betyder förvaringsplats.. och ett skrivbord är just en typ av förvaringsplats för dom som gillar att lägga sina saker där (hmm, ni ska inte se mitt skrivbord, där ligger all möjlig skit :P)
Jag brukar först blanda in Service när jag ska hantera flöden.. dom blir mer som fasder mot modellen.. Sedan går jag ofta mot mina Repositories för att hämta upp root aggregaten "entiteter" eller Value objects etc. Men vill du ha en enhetlig lösning, så skulle du alltid kunna gå mot dina Service istället för Repositories.. det är väldigt många som gör så.. de skapar även Service per Use Case.Sv:"Best pratices" för tex kund & order relationerna?
Dvs i t.ex. en asp.net mvc applikation som bara är en webbapp så tycker jag att man kan arbeta med repositories direkt Controllererna. Sedan om nu applikationen skulle gå över till att bli en för både webb och desktop ja då kanske det är dags att börja tänka på att föra över logik från controllern till en ett extra skikt. Tänker jag rätt här?
Men som du säger, en repository kan ju lika gärna vara/är en del av modellen.Sv:"Best pratices" för tex kund & order relationerna?
Angående interfacet... skriver ihop något snabbt (repository)
public ICustomerOrderSet GetCustomerById(int id)
//Customerentiteten
public class Customer : ICustomer, ICustomerInvoice, ICustomerOrderSet
//Customer-interface
public interface ICustomer
{
int Id { get; }
string FirstName { get; set; }
...
//ICustomerOrderSet-interface
public interface ICustomerOrderSet : ICustomer
{
IList<Order> Orders { get; }
...
Om jag nu anropar GetCustomerById så får jag ett gränssnitt för en kund med en orderkollektion och inte en fakturakollektionen. Det optimala skulle vara att interfacet i GetCustomerById är generics så att man i tex GUI:t väljer vad är det för interface jag vill jobba med. Men jag antar att det bryter mot "Interface-Segregation Principle" eller?Sv: "Best pratices" för tex kund & order relationerna?
Ja för som standard kommer klienten (användaren) att få flera members som den inte bryr sig om, iofs kan du lösa detta genom factories och sätta konstruktorn till internal eller protected, så bara dina facotries kan skapa dom, men tänk dig hur stor din entitet blir och jag skulle inte våga ändra i den, sedan så bryter den mot Singel-Responsibility Principel genom att den kommer få flera skäl till att ändras vid olika tidpunkter. Om du har Eric Evans book Domain Driven Design, ta en titt på "Strategic Design", där skriver han om bound context och context map etc, där context map handlar om att mappa en model med en annan model som används inom olika context.Sv:"Best pratices" för tex kund & order relationerna?
Sv: "Best pratices" för tex kund & order relationerna?
Om vi antar att vi har ett exempel "Bil", "Person" och "Ägare"; då skulle man kunna definiera bil separat, person separat, och _om_ ägare definieras, så får man plötsligt anropen:
Bil.Ägare()
och
Person.ÄgdBil()Sv:"Best pratices" för tex kund & order relationerna?
>person separat, och _om_ ägare definieras, så får man plötsligt anropen:
>Bil.Ägare()
>och
>Person.ÄgdBil()
Förstår jag dig rätt? Du skapar en relation mellan bilar och personer som heter Ägare.
Så med din syntax ovan skulle jag kunna göra:
jag = new Person();
bil = new Bil();
bil.Ägare = jag;
Assert.That(jag.ÄgdBil, Is.EqualTo(bil));
Det kan man nästan göra i C# (måste lägga till paranteser eftersom det inte finns extension properties) och antagligen på samma sätt i C++0x med Concept Maps
i C#
static class BilRegistret {
private static Dictionary<Person, Bil> register = ...
public static void Ägare(this Bil b, Person p) { register.Add(p,b); }
public static Bil ÄgdBil(this Person p) { return register[p]; }
}
jag = new Person();
bil = new Bil();
bil.Ägare(jag);
Assert.That(jag.ÄgdBil(), Is.EqualTo(bil));
I statiska språk föredrar jag dock Ägare(bil, jag) före bil.Ägare(jag).Sv: "Best pratices" för tex kund & order relationerna?
Dvs en Person har flera bilar, en bil har en ägare.
Dock så om vi säger som tidigare en person bär ju inte omkring på sina bilar utan har dem antagligen i ett garage?
Så garage.TaUtBilarÄgdaAv(Person) / Bilregistret.HämtaRegistrerningsNummerÄgdaAv(Person), även om min första tanke faktistk är Person.ÄgdaBilar().
Jobbig tankenöt ;(, antar att svaret är det beror på hur domänen ser ut och applikationen till stor del bygger på den kopplingen.Sv:"Best pratices" för tex kund & order relationerna?
Problemet med ditt garage är att anledningen till att du skapar garaget är att du inte vill in och mecka i Person- och Bil-klasserna, du vill hålla dem rena. Att ha både en
List<Bil> MinaBilar
i Person och en
Person Ägare
i Bil är fult på många sätt; du får duplicering med allt vad det innebär (anomalier och minnesslöseri), men det ligger ändå något mycket logiskt i det. En bil har en ägare, en person kan äga ett antal bilar.
Som sagt - om nu inte Martins förslag funkar (som såvitt jag såg innefattar extension methods, vilket i mitt tycke är något tveksamma tillägg, men det ser helt korrekt ut) - så anser jag att det är en brist i språket snarare än en designbeslut som man ska behöva ta.
Man ska ha klart för sig att den OO som finns i C# och Java (och som i mångt och mycket bygger på hur man löste det i C++ - ett språk som uttalat <b>inte</b> är ett enbart oo-språk) är långt ifrån det enda sättet att göra det på. Kolla på Obj-C och CLOS för två andra exempel.Sv: "Best pratices" för tex kund & order relationerna?
Jag la bara fram det som ett förslag :), jag vet inte riktigt vad jag tycker exakt hur man skall göra i detta fallet, jag tror inte det finns någon silverbullet.Sv:"Best pratices" för tex kund & order relationerna?
Anledningen till att det ser ut som det gör har ju att göra med den direkta kopplingen mellan "referens till objekt" och "pekare". Motsvarande hade man knappast hade accepterat med klasser; "klasser" och "strukturer med funktioner och scope". Det hade varit alldeles för vekt; ändå är det ok för associationer.Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
Jag köper dock argumentet om att tex en kund kan bli ett komplext objekt om ovanstående går att göra. Men jag tycker som sagt att komplexiteten och prestandan borde gå att hantera på annat sätt.Sv: "Best pratices" för tex kund & order relationerna?
Att kundobjektet blir komplext är egentligen inte ens sant, utan ett problem med intellisensen och att man har blivit så beroende av den. Hade intellisensen förstått vad vi ville arbeta med hade problemet varit löst; kanske mha namespaces?Sv:"Best pratices" för tex kund & order relationerna?
Ägare.Bil
Här har vi annat intresant exempel, en ägare i detta fall är inte = Person objekt, utan ett helt nytt objekt, där person tar en annan roll i ett helt annat context..Ett Ägare objekt kan ha helt andra egenskaper än en Person..
Finns en bra bok "Object Thinking", har inte författaren namn i huvudet sitter nämligen på tåget nu, men han menar på att system skulle vara fungera betydligt bättre om vi tänker som ett objekt och inte som en dator.
Det är domänmodellen som styr hur vi ska designa vårt system, men vi kan få begränsningar pga tex språket vi använder oss av, så vi får hitta på andra lösningar..
En annan sak som jag ofta ser, och det är att många tänker i rellationer när det jobbar med objekt, och inte ur ett mer objet-orienterat perspektiv.Sv: "Best pratices" för tex kund & order relationerna?
Det där är ju fel - en bil <b>har</b> en ägare. Däremot är innebörden av "har" i klassisk oo starkt anpassad till de strukturer som finns i språket.
<b>>En annan sak som jag ofta ser, och det är att många tänker i rellationer när det jobbar med objekt, och inte ur ett mer objet-orienterat perspektiv.</b>
Jag skulle nog säga att relationer är ett vettigt sätt att se det på, bara det att man skulle behöva en rikare definition av relationer än den som finns i databaser. Den enda typen av relation vi har idag är en futtig pekare.
<b>>Det är domänmodellen som styr hur vi ska designa vårt system, men vi kan få begränsningar pga tex språket vi använder oss av, så vi får hitta på andra lösningar.. </b>
Och jag menar att det inte blir domänmodellen som styr designen, utan att alla har en inbyggd dragning åt vad som finns i ens språk. Jag tycker att steget strukturer -> objekt mycket väl skulle kunna få ett till; objekt -> "vettiga relationer + objekt".
Som sagt: Om klasser hade varit struct:ar med funktioner så hade vi knappast haft den oo vi har idag. Ändå behåller vi simpla pekare...?Sv:"Best pratices" för tex kund & order relationerna?
Det där är ju fel - en bil har en ägare. Däremot är innebörden av "har" i klassisk oo starkt anpassad till de strukturer som finns i språket. "
Jag utgår från att vi inte kan fråga bilen vem som är ägaren av den, eller se på bilen vem som äger den.. så vi kan inte skriva Bil.Ägare om inte modellen tilllåter det.. Men självklart har bilen en ägare, men om vi ska tänka som ett objekt, och bilen är ett objekt, så kan vi inte fråga den "vem är din ägare". Den har inget intresse av att veta det, den kan inte veta det.. om vi utgår från verkligheten. Sedan kan det diskuteras om bil ska ha en egenskap ägare.. svaret är JA eller Nej, det beror på vår domänmodell som är skapad tillsammans med en domänexpert. Om denna expert anser att bil ska veta om dess ägare, så har den en ägare, annars inte. Kan återigen tipsa om boken Object Thinking
http://www.amazon.com/Object-Thinking-DV-Microsoft-Professional-David/dp/0735619654, intresant att läsa David syn på hur vi ska tänka när vi bygger applikationer.
Självklart kan ett objekt ha en relation till en annan, men många designer sina objekt efter databasen. Skulle varit mer tydlig där.
"tex språket vi använder oss av, så vi får hitta på andra lösningar.. </b>
Och jag menar att det inte blir domänmodellen som styr designen, utan att alla har en inbyggd dragning åt vad som finns i ens språk. Jag tycker att steget strukturer -> objekt mycket väl skulle kunna få ett till; objekt -> "vettiga relationer + objekt"."
Kan tyvärr inte hålla med dig, det är domänmodellen som vi tar fram tillsammans med en domänexpert som styr hur vår modell kommer att se ut.. Det är viktigt att vi utvecklare pratar samma språk som kunden. Eric Evans skriver om detta under Ubiquitous Language.. OBS! Jag är en DDD "kille", så jag utgår ofta från DDD.Sv: "Best pratices" för tex kund & order relationerna?
<b>>Kan tyvärr inte hålla med dig, det är domänmodellen som vi tar fram tillsammans med en domänexpert som styr hur vår modell kommer att se ut.. Det är viktigt att vi utvecklare pratar samma språk som kunden. Eric Evans skriver om detta under Ubiquitous Language.. OBS! Jag är en DDD "kille", så jag utgår ofta från DDD.</b>
Återigen, det är inte det jag säger. Det jag säger är att det är helt oväsentligt vilken utvecklingsmetodik etc. du använder - så länge du har tänkt skriva objektorienterat så är det så att mainstreamspråken har en dålig korrelation till vad man borde kunna göra i oo. Alltså så kommer din modell att tydligt formas efter det språk som du utgår ifrån.
Om du säger att "en anställd är en person" så tänker du undermedvetet på att "detta ska förmodligen implementeras som ett arv" eller "detta ska förmodligen implementeras som ett interface", just eftersom du jobbar i C# och kan is-a-regeln.
Men skulle det t.ex. vara Javascript så skulle du snarare säga att "en anställd har förmodligen typ samma grejer som en person", och du skulle kanske inte ens säga att "en anställd är en person", utan något i stil med "förutom de egenskaperna en person har, så har en anställd också ett anställningsnummer". I andra objektorienterade språk hade ordvalen varit andra. Din domänmodell kommer påverkas av vad du arbetar i för språk.Sv:"Best pratices" för tex kund & order relationerna?
För att göra det mer tydligt så kommer inte själva domänmodellen påverkas, utan implementationen av den. så Absolut kommer språket kunna påverka hur den implementeras! Som jag nämde i ett tidigare inlägg så kan språket sätta stopp för vad vi kan implementera eller inte, och hur vi implementerar vår modell. Rätt intresant, borde vi inte välja språk som gör det lättast för oss att implementera vår domänmodell så lik modellen som möjligt?! Vi borde, men vi kommer få problem vid förvaltning.. alla kan inte alla programmeringspråk och vi kan inte kräva det..Sv: "Best pratices" för tex kund & order relationerna?
Sedan håller jag med om att domänmodellen behöver inte ändras beroende på vilket språk man implemmenterar det i utan det är implemmentationen som kan se lite annorlunda ut.
Fredrik du har iallfall övertygat mig till ett bokköp :).Sv:"Best pratices" för tex kund & order relationerna?
Om vi säger så här istället - låt säga att du av någon anledning skulle göra en domänmodell utan att veta ett smack om oo - vad hade du gjort då?
Då hade du beskrivit situationen som ett antal olika processer och procedurer, kanske hintat lite lätt om att "det finns ett antal funktioner som alla tar en anställd som första parameter", vilket skulle motsvara "metoder" idag. Men du hade inte sagt att "en anställd är en person", för det är inte relevant eller användbart i ett procedurellt språk, du hade inte kommit på tanken att säga det.
Jag menar att det är exakt det problemet vi har med relationer idag. Vi beskriver relationer som "känner till" eller "har" bara för att det enda vi känner till är "basic pekare".Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
<b>>det finns enligt mig ingen anledning att göra en domänmodell om man inte kan eller vet vad OO är</b>
Men om den oo vi har tillgång till i de språken vi använder inte på något sätt är unik eller enda sättet att definiera oo, hur vet du då att du inte är begränsad i hur du gör din domänmodell?
Nu är jag mycket dåligt insatt i DDD, men jag misstänker att det inte finns någon principiell orsak till att det måste vara ett av C++-oo-språken för att kunna använda metodologin, och av det lilla jag har sett av DDD, så kan jag inte se något som hindrar en från att göra samma sak i en procedurell miljö. Sv: "Best pratices" för tex kund & order relationerna?
Rent principellt så går det säkert att implementera en DDD lösning i en procedurell miljö, lika så kan man använda sig av vattenfalls metoden för att implementera DDD, rent teoretiskt alltså. Rent teoretiskt så kan jag använda min Fiat 500 när jag skall flytta till ett nytt hus ifrån mitt gammla också, rent praktiskt så låter jag bli.
Så rent praktiskt så använder man oo-språk och agile utvecklingsmetoder när man pratar om DDD. Vilket givetviss kommer sätta sin prägel på hur du implementerar domänmodellen. Men själva domänmodellen bör inte vara beskriven med utgångs punkt ur OO, eftersom domänexperterna oftas inte har någon utvecklingsbakgrund och inte förstår vad OO är för något och hur det implementeras.
- MSv:"Best pratices" för tex kund & order relationerna?
Enligt Fredrik Normén tidigare i koden:
<b>>det är domänmodellen som _vi tar fram tillsammans_ med en domänexpert som styr hur vår modell kommer att se ut..</b>
Alltså så är det inte domänexperten som ensam tar fram modellen => din bakgrund inom oo styr modellens utformning.
Eller funkar det lika bra om en domänexpert helt utan kunskaper om programmering tar fram domänmodellen själv?
Om inte, varför?Sv: "Best pratices" för tex kund & order relationerna?
Visst är det teoretiskt tänkbart, men återigen knappast praktiskt,
"Alltså så är det inte domänexperten som ensam tar fram modellen => din bakgrund inom oo styr modellens utformning. "
Det är ju knappast bara min bakgrund inom OO som styr modellens utformning, det är hela knuskapsbanken som jag har i bakhuvudet som är med och jobbar, och hittar problem och lösningar som dykt upp i andra tillfällen. Och om OO nu är det mest praktiska att implementera modellen i så skulle det vara bra korkat att inte använde de kunskaper som man har inom OO när modellen skall utformas.
Om 2 år så kanske det kommit något annat sätt att implementera modellen i som är mer lämpligt, men just nu så är det OO och att inte använda sin kunskap inom OO vore korkat. Man skall dock vara försiktig att tillämpa OO för hårt i modellen, eftersom den skall kunna förstås av folk som inte har någon anning om OO. Men oftas så kan folk relatera till OO så det brukar inte vara så svårt att förstå.
- MSv:"Best pratices" för tex kund & order relationerna?
Ergo: Du tar de facto fram modellen ur ett oo-perspektiv, som i sin tur baseras på C#. Jag gissar att det är det du använder, oavsett så är det väl från C++-familjen av oo? Och om det oo-perspektivet inte är det enda tänkbara?
Om det dels finns andra sätt i grunden att lösa det på (fortfarande objektorienterat), och dels om det saknas högre abstraktioner i de språken du använder, som hade varit vettiga att använda, men som du inte känner till, så speglas det i domänmodellen.
Vi kan ta det här testet istället: Om du gör en domänmodell, kommer du aldrig någonsin på tanken att "det kan vara ett event", och uttrycker dig annorlunda vad gäller events i själva modellen?
Det känns lite som att jag är för dålig på att förklara vad jag menar, hela poängen går aldrig riktigt fram. Ska kanske skriva ihop det här som en lite mer sammanhängande text och lägga upp någonstans... jag tror att "ni" kan tycka att det är intressant, men att jag bara rör ihop det när jag gör korta svar här...Sv:"Best pratices" för tex kund & order relationerna?
Det här får mig att tänka på frågeställningen "Är det okej att röka när man ber? Är det okej att be när man röker?" På den första vill man svara nej, medan man på den andra vill svara ja. (Om ni är antireligiösa extremister kan ni förstås byta ut "be" mot något annat passande.)
Här är två olika situationer:
* du skall utveckla ett system där OO passar bra; du får fritt välja metodik och språk
* du skall utveckla ett system där OO passar bra; du får fritt välja metodik men måste använda ett språk utan inbyggt stöd för OO
I första fallet skulle du säkerligen välja DDD som metodik och C# som språk (alt. C++ eller Java beroende på situation).
I andra fallet kanske du är tvungen att använda C som inte har direkt stöd för OOP. Men vilken metodik skulle du välja? Skulle du inte använda DDD där också, fast kanske tänka litet annorlunda eftersom det inte finns arv och annat som är vanligt i OO-språk?
Eller menar du att DDD är olämpligt och opraktiskt om man inte har ett språk med stöd för OO?Sv: "Best pratices" för tex kund & order relationerna?
Nu har jag inte gjort så många domänmodeller för just DDD, men man har ju programmerat OO ett tag där tagit fram något som liknar en domänmodell. Och jag har nog aldrig tänkt så som du tänker med events precis när jag skapar domänmodellen, men efter mer insikt hur modellen fungerar så ändrar man i den, och det är mycket möjligt att man ser en lösning med hjälp av events som kan förändra och förenkla min domänmodell, och därmed så kommer den att ändras.
Men det är ju liksom hela poängen att domänmodellen kommer att ändras under tidens gång när man får mer insikt hur den fungerar, och inser att visa saker är onödiga och andra måste läggas till, och de insikterna får man från hela sin kunskapsbank, och även med hjälp av lösningar i din kod och vektyg. Kan du inte implementera en lösning på ett visst sätt för att verktygen hindrar dig ifrån det, så måste du ju anpassa domänmodellen till det, och finns det verktyg som gör att du kan implementera din domänmodell på ett bättre sätt, så bör du ju använda dessa verktyg.
- MSv:"Best pratices" för tex kund & order relationerna?
Och om det inte finns events i språket - då hade du inte ändrat modellen?
Kan det då inte vara så att du köper oo-modellen i C# rakt av, utan att ifrågasätta den? (Och med "du" så menar jag inte dig utan alla.)
Det är det jag menar, diskussionen handlar (för min del) egentligen inte om domänmodeller eller DDD.
<b>OO a'la C++/Java/C# är underutvecklat; det saknas konstruktioner som borde finnas.</b> Ändå accepteras det. Bidirectional relations är något som ett OO-språk borde ha stöd för, men det har det inte; lika väl som att class-scope är något som ett OO-språk borde ha stöd för.Sv: "Best pratices" för tex kund & order relationerna?
Olämpligt vet jag onte eftersom jag aldrig testat att implementera en DDD lösning i ett språk utan OO, men det är nog garanterat svprare och mer komplicerat då domänmodellen ju är "uppbyggd av" objekt.
- M Sv: "Best pratices" för tex kund & order relationerna?
Köper och köper, det är så min verklighet ser ut idag, imorgon kanske OO modellen ser annorlunda ut, men jag låter ju inte bli att användaden även om den inte är perfekt.
Generics fanns ju inte innan .NET 2.0. Har de förenklat mitt liv som utvecklare, javisst! Lät jag bli att använda .NET 1.1 för att Generics inte fanns, Nej.
Även om det saknas saker i språket så hänger jag itne upp mig på det och använder det för att implementera modellen så gott det går i det språket jag använder, eller försöker lära mig ett annant språk som kan hjälpa mig mer.
Jag vet inte riktigt vart du vill komma egentligen? Klart det finns brister inom språken och verktygen, men skall vi låta bli att använda dem idag för att de kommer fungerar bättre imorgon?
- MSv:"Best pratices" för tex kund & order relationerna?
"Som jag ser det är det här en brist i de objektorienterade språken snarare än något annat."
Som ett argument mot argumenten att "kunden blir 'fet'", och de generella problemen med redundant data som uppstår. Jag menar att "relationer" borde vara något mer än en futtig pekare.Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
Alltså något i stil med:
class Person{
string name;
...
}
class Car{
...
}
relation Ownership<Owner Person, Owned Car>
{ }
...
Person me;
Car volvo;
me.owned = volvo;
volvo.owner.name = "Niklas";
Där båda klasserna helt enkelt utvidgas med en pekare åt varje håll (och förstås automatisk kod för att de inte ska kunna få anomalier). Om man aldrig använder ena halvan av relationen så räcker det att generera ena pekaren, osv. Man kan också tänka sig att kompilatorn gissar att andra implementationer är bättre; säg någon typ av dictionary som i Martin Adrians exempel ovan, en indexerad array åt något eller båda hållen, osv; beroende på hur koden ser ut, vad som ändras.
Sen är det ju en fråga om exakt hur det ska designas, hur *-1 ska utformas, osv. Språkdesign är svårt - det är därför det tar många år att hitta på nya språk, och det kan förstås vara otroligt knepigt att få till de här grejerna på implementationsnivå, men det är arv också.Sv:"Best pratices" för tex kund & order relationerna?
Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
Tyvärr är det som sagt tämligen svårt med språkdesign, så jag vågar inte gissa vad som är möjligt och vad som är rimligt. C++ har väl ett 10-tal nya (ganska enkla) språkkonstruktioner i C++0x som sannolikt kommer under nästa år, och det sen senaste versionen C++03 sen 2003, det visar ju lite på att det tar sin lilla tid...Sv: "Best pratices" för tex kund & order relationerna?
Tabeller i en relationsdatabas utgör relationer. Ofta är de även funktioner (dvs givet ett värde på en kolumn får man ut ett exakt ett värde i en annan kolumn), men vissa av dem kopplar ihop flera objekt/entiteter (t.ex. företag - anställd - tidpunkt). Samma sak med klausuler i Prolog. Så avancerade relationer finns ju i vissa system och språk.Sv: "Best pratices" för tex kund & order relationerna?
Sedan vill jag inte att de automatiskt skall dyka upp för att jag kanske inte vill att andra utvecklare skall använda relationen vid arbete av ett av objekten. Som automatiskt hade fått bidirectional referensen.
Jag tycker faktiskt att OO språken är helt okej och fungerar jättebra.
Det som du eftersöker borde dock kunna fungera att få till i ett dynamiskt språk :).Sv:"Best pratices" för tex kund & order relationerna?
Sv: "Best pratices" för tex kund & order relationerna?
<b>>Tabeller i en relationsdatabas utgör relationer.</b>
Mm... och det är lite min förebild, men precis som arv (för att inte tala om metoder osv.) representeras väldigt dåligt i en relationsdatabas, så är det lite grejer jag saknar där. Du kan göra lite constraints på enklare grejer, men hur undviker du säg, en cirkulär relationskedja? (Låt säga "förkunskapskrav på kurser", jävligt dumt om det blir i en cirkel...)
Det är därför jag vill ha tillgång till hela språket på en gång. Jag har tyvärr bara de mest rudimentära kunskaperna om Prolog (och det finns prolog-baserade databaser - kolla på AllegroCache), men om jag inte minns fel så kan det vara hyfsat knepigt att definiera vissa regler (säg n-n, men en enskild person kan äga max 3 bilar).
Oavsett - jag skulle inte kalla Prolog objektorienterat, och det är ju just de objektorienterade språken som jag tycker saknar det. Har för dålig koll på Objective C för att uttala mig om implementationen där.Sv:"Best pratices" för tex kund & order relationerna?
Det som Niklas J och jag menar är inte att det bidirectional ska ske "automatiskt" utan det är någon form av inställning som man måste sätta manuellt när tex association dras. Man ska ha en valmöjlighet. Det är det som Niklas J vill lyfta fram.
-> Fredrik
Fredrik, du har koll på EF men det är öppet för andra att svara också :) Finns inte denna möjlighet i EF, dvs att du slipper göra bidirectional?Sv: "Best pratices" för tex kund & order relationerna?
Skall jag använda en SOA eller en OO lösning?
Problemen med att Customer blir fet är ju egentligen att i en större lösning så blir det problem med att mycket data måste laddas för att OO modellen är såpass kopplad, isf kanske en SOA lösning är att föredra?Sv:"Best pratices" för tex kund & order relationerna?
Använder du events?
Tycker du att de är en rimlig del av språket?
Du skulle precis lika väl kunna köra med observers, men events "känns oo", medan observers mer är en workaround för att events inte finns. Jag tycker samma om "pekare" och "relation".
Jag <b>kan</b> göra en lista med order-pekare i kunden och en pekare till kund i ordern, men då måste jag hantera alla typer av problem som kan uppstå. Det är inte säkert att det är det bästa, en hashtabell kanske hade varit bättre - eller två. Men det är en optimeringsfråga, och det föredrar jag att få hos kompilatorn...Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
Jag tycker det handlar om OO. Det handlar som Niklas J försöker lyfta fram är en effektivitivare implementering av bidirectional. Han menar inte att man ska köra bidirectional på allt utan som sagt när det behövs så ska man lättare kunna implementera det.
Förresten, finns det inget svenskt ord för bidirectional :)Sv: "Best pratices" för tex kund & order relationerna?
Och då drog jag paralleler till om man bör ha relationerna överhuvudtaget i SOA. I OO köper jag att man vill ha dom i SOA vill man antagligen inte ha dom. Därför tog jag upp det ämnet.Sv:"Best pratices" för tex kund & order relationerna?
I SOA vill man hellre ha standardmässiga hierarkiska strukturer än proprietära beskrivningar av relationer mellan objekt. (Och absolut inte några 'tekniska' metodandrop typ LazyLoad()) T.ex. skulle man i SOA definiera ett XML-schema enligt nedan. Eller varför inte dra nytta av publika standarder som UBL. Jag tycker att det är smartare att fokusera på detta. Dvs vilka tjänster har vi, vad exponerar dem, vad är vår vokabulär för dessa tjänster.. ? (det borde vara viktigare, än att stirra sig blind på hur man bäst mappar SQL-tabller till interna objekt).
<code>
<OrderMsg>
<Order>
<Header>
<Customer>
<ID></ID>
<Name></Name>
</Customer>
</Header>
<Detail/>
</Order>
</OrderMsg>
</code>Sv: "Best pratices" för tex kund & order relationerna?
Sv:"Best pratices" för tex kund & order relationerna?
Problemet är väl att vissa inte riktigt vet vad det är och ska ha det bara för att det är hype.. därmed kan man inte ställa rätt krav och man hamnar snett... Man drar för stora växlar på hela begreppet.. varför inte bara se det som att man exponerar återanvändbara systemmoduler som Web services och låta utvecklare fixa det, lite i taget, då funkar det... Vad är förresten ett "SOA projekt", har alltid undrat det... Det låter inte som ett projekt jag skulle vilja vara med i.. :) Sv:"Best pratices" för tex kund & order relationerna?
Om vi skall göra ett system tjänsteorienterat menade jag att relationerna mellan entiteterna bör hållas väldigt få. Möjligtvis att dom kopplas ihop hos klienten i en ViewModel eller liknande.Sv: "Best pratices" för tex kund & order relationerna?
Niclas:
Jag gillar dina tankar kring relationer mellan objekt och att det borde vara mer än en "liten pekare".. En kund körde med attribut för att definiera relationer istället för egenskaper.. de tyckte det funkade bra.. jag har inte själv sett det, så jag vill inte utala mig så mycket om det. men dom var nöjda i alla fall..Sv:"Best pratices" för tex kund & order relationerna?
Detta är vad jag har kommit fram till och även de som jag har läst av.
Är målmiljön en desktop applikation där varken minne eller cpu är ett problem så bör man ha en OO-modell som har de mesta kopplat dvs Kunden har flera ordrar osv. I en desktopmiljö så finns även all data kvar i minnet så att den kan återanvändas varje request en användare gör vilket kan göra en ihopkopplad modell enklare att arbeta med.
Är det däremot en serviceorienterad miljö / webb / distribuerat, så bör man kanske tänka lite annorlunda en kund bör kanske då inte ha en referens till alla ordrar då det kan bli ganska tungt att ladda alla ordrar t.ex. dock kanske en Order bör ha en lista med OrderLines då det bara är Order som arbetar med Orderlines och OrderLines är vad en Order egentligen arbetar med. Här kan man då låta servicerna sköta relationerna t.ex. orderService.GetOrdersByCustomer(object id);
Sedan tycker jag även att Context frågan skall komma in, är systemet t.ex. inte ett Ordersystem utan ett mycket större system som hanterar massor ja då kanske man inte alls skall ha någon objektreferens i desktopmiljön heller, men oftast så tror jag att det fungerar.
Det är nog mitt svar på huvudfrågan. Det var nog jag som blandade in SOA i hela tråden så jag har mig själv att skylla. :)Sv: "Best pratices" för tex kund & order relationerna?
Du vill skapa en abstraktionsnivå inte för att vara vag utan för att kunna vara precis. Att ha en stor modell som klarar allt är inte att vara precis.
Om du tex har en faktura som har en relation till sin kund, samma kund typ används i CRM modulen för applikationen likväl som i faktura delen, vad händer då om CRM delen har krav på kundtypen som inte passar fakturan?
Eric Evans har skrivit väldigt mycket om andar anledningar till det här, läs gärna kapitlet om aggregate eller strategic design från hans bok. Jag hade ett seminarium på öredev också som kommer upp som film snart på www.oredev.se. Sv:"Best pratices" för tex kund & order relationerna?
Jo jag såg ditt seminarium, det var mycket intressant och bra.
Om man tittar på detta problemet så är det så att det kanske skall till en annan typ av Customer i detta fallet, relationen mellan Customer och Order kan fortfarande ligga kvar, men den Customertypen kanske inte bör användas och kopplas utanför Ordermodulen i ett sådant system allt beror iof på kraven.
Det jag menar med att det kanske bör vara skillnad på modellen om man systemet är tillämpat för en desktopmiljö gentemot en tjänsteorienterad miljö är att i en desktopmiljö kan man dra nytta av objektreferenser och möjligtvis lazyloading medans i en tjänsteorienterad miljö så försvåras detta.
T.ex. på det senaste har jag arbetat med ekonomidata där vi har entiteter som Organisationer, räkenskapsår, Verifikationer, transaktioner
I ett sådant litet system så fungerar det utmärkt med att Organisationer har räkenskapsår som i sin tur har verifikationer som i sin tur har transaktioner i en desktopmiljö. För att organisationsentiteten används enbart inom det contextet i applikationen.
I en tjänstorienterad miljö hade jag däremot sagt att det hade varit en dum ide att göra på detta sättet eftersom lazyloading och bristen på tillstånd hade gjort det till en mycket dålig lösning rent prestandamässigt när det kan handla om miljoner av transaktioner under ett räkenskapsår och att hämta det under varje request hade inte gått.
Men jag tror att du missuppfattade mig, jag tänkte nog på applikationer i mindre skala. Därför skrev jag med just att relationen kanske inte är motiverad i ett storskaligt system.Sv: "Best pratices" för tex kund & order relationerna?
Udi Dahan sa något intressant vid ett tillfälle: "Ebay didn't know they where building ebay five years ago" i en diskussion om "nedless complexity". Vad han menade, vilket jag håller med till fullo, är att även i små system behöver man följa vissa principer för stora system för att underlätta förändring när den händer.
Att inte skapa en domänmodell för hela systemet skulle jag vilja hävda är just en sådan princip.
>> men den Customertypen kanske inte bör användas och kopplas utanför Ordermodulen
Det här är en riktigt sund princip att följa. En kund är kanske samma kund i fysisk person för experter på orderhantering och experter på CRM, men de värderar oftast olika aspekter olika högt.
Btw, don't get me started on Lazy Loading ;)
Jag tycker det är tråkigt att man, istället för att bygga korrekta modeller och Repositories som är väldigt specifika, använder Lazy Loading. Ofta brukar lösningar med Lazy Loading se oerhört effektiva ut till en början men ju mer ett system växer desto oftare hamnar man i disskusioner runt vad som skall lazy laddas, när och vad som skall eager laddas och hur vi skall hantera load span strategier.
Det slutar oftast med lika mycket och mer komplex kod än om modellen helt enkelt varit precis från första början. För att inte tala om hammaren som DBAn slår i huvudet på en när man glömt bort att den där listans alla relationer var lazy loaded och databasen hickade till.