SlideShare a Scribd company logo
1 of 18
Vad är poängen med domändriven
design?
Peter Backlund, Citerus AB
peter.backlund@citerus.se




                                 1
Vad är poängen med domändriven
design?
Peter Backlund, Citerus AB
peter.backlund@citerus.se




                                 2
Domän: elektroniska passersystem/bokning




                                           3
Vad vi hade
PeriodConfiguration getPeriodConfiguration(long   personId, 
                                           long   resourceGroupId,       
                                           long   bookersAccessCategoryId, 
                                           long   from, 
                                           long   to)



 • Utspridd logik

 • Svag eller beteendelösa typer

 • Svårt att studera, testa och förstå




                                                                              4
Vägen till en kraftfull modell

                       • Domänexpert


                       • Strukturera kunskap


                       • Gemensamt språk




                                               5
"Ok, vi säger att en lägenhet vill boka tvättstuga 3 den
       22:a oktober mellan 14.00 och 18.00..."




                                                           65
Bokningsförfrågan
public class Bokningsförfrågan implements ValueObject<Bokningsförfrågan> {
 
  Bokare bokare;
  Bokningsobjekt bokningsobjekt;   
  Pass pass;
  ...
 
}




                                                                             7
"Man ska kunna ställa in så att om du
har bokat tvättstugan exempelvis tre
gånger den här månaden och alla
bokningar är aktiva så ska det inte gå
att boka en gång till förrän man har
tagit bort nån bokning eller man har
använt tvättiden, eller det blir en ny
månad.”

”Det är viktigt därför att vi har upptäckt
att folk bokar upp massor med pass
och då ... vilket leder till att ... och ...”


                                                85
Struktur




           9
Struktur

En av flera bokningsregler lyder:

Ett bokningsobjekt ska kunna ställas in så att antalet
bokningar per bokare per månad är begränsat till X st.

En bokningsförfrågan tillåts om bokaren har färre än X
aktiva bokningar av det bokningsobjektet under den
månad då passet infaller, eller om ingen begränsning är
satt.




                                                          10
public class PerMånadPerBokareBegränsning implements Bokningsregel {

  @Override
  public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {
   [...]
  }
   
}




                                                                       11
public class PerMånadPerBokareBegränsning implements Bokningsregel {

   @Override
  public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {
    Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();
    Regelinställningar inställningar = bokningsobjekt.inställningar();
    Integer antal = inställningar.perMånadPerBokare();
        
    [...]
  }
  
}




                                                                       12
public class PerMånadPerBokareBegränsning implements Bokningsregel {

  @Override
  public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {
    Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();
    Regelinställningar inställningar = bokningsobjekt.inställningar();
    Integer antal = inställningar.perMånadPerBokare();
        
    if (ejAngivet(antal)) {
     return true;
    } else {
      [...]
    }
  }

}




                                                                       13
public class PerMånadPerBokareBegränsning implements Bokningsregel {

  @Override
  public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {
    Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();
    Regelinställningar inställningar = bokningsobjekt.inställningar();
    Integer antal = inställningar.perMånadPerBokare();
        
    if (ejAngivet(antal)) {
     return true;
    } else {
      Pass pass = bokningsförfrågan.pass();
     Bokare bokare = bokningsförfrågan.bokare();
      CalendarInterval passetsMånad = månadFörPasstart(pass);
      [...]
    }
  }

}




                                                                       14
public class PerMånadPerBokareBegränsning implements Bokningsregel {

  @Override
  public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {
    Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();
    Regelinställningar inställningar = bokningsobjekt.inställningar();
    Integer antal = inställningar.perMånadPerBokare();
        
    if (ejAngivet(antal)) {
     return true;
    } else {
      Pass pass = bokningsförfrågan.pass();
     Bokare bokare = bokningsförfrågan.bokare();
      CalendarInterval passetsMånad = månadFörPasstart(pass);
      List<Bokning> bokningarUnderMånad = 
          bokare.listaAktivaBokningar(bokningsobjekt, passetsMånad);

      return bokningarUnderMånad.size() < antal;
    }
  }

}




                                                                       15
En kraftfull modell
public class Bokningsobjekt {

    List<CalendarDate> dagarMedLedigaPass(Bokare bokare,
                                          CalendarInterval intervall) {}

    List<Pass> ledigaPassUnderDag(Bokare bokare, CalendarDate dag) {}

}




                                                                        16
private CalendarInterval månadFörPasstart(Pass pass) {
  TimePoint passtart = pass.somIntervall().start();
  CalendarDate datumFörPassStart = passtart.calendarDate(TIDSZON);
  return datumFörPassStart.month();
}




                                                                     17
Mer information
dddsample.sf.net


www.citerus.se/ddd


www.infoq.com/minibooks/
domain-driven-design-quickly




                               18

More Related Content

Viewers also liked

Viewers also liked (20)

20世纪中国两次和平转型的机会
20世纪中国两次和平转型的机会20世纪中国两次和平转型的机会
20世纪中国两次和平转型的机会
 
7.11.2009 Ppt
7.11.2009 Ppt7.11.2009 Ppt
7.11.2009 Ppt
 
tecnologia e informatica
tecnologia e informaticatecnologia e informatica
tecnologia e informatica
 
tecnologia e informatica
tecnologia e informaticatecnologia e informatica
tecnologia e informatica
 
Reglamento0809
Reglamento0809Reglamento0809
Reglamento0809
 
amigos
amigosamigos
amigos
 
Halloween
HalloweenHalloween
Halloween
 
Nikit
NikitNikit
Nikit
 
Ola
OlaOla
Ola
 
lit
litlit
lit
 
Presentacio Espaistreballs
Presentacio EspaistreballsPresentacio Espaistreballs
Presentacio Espaistreballs
 
Webcast Ibri Outubro 2009
Webcast Ibri Outubro 2009Webcast Ibri Outubro 2009
Webcast Ibri Outubro 2009
 
Nirogi Mata Dr. Shriniwas Kashalikar
Nirogi Mata Dr. Shriniwas KashalikarNirogi Mata Dr. Shriniwas Kashalikar
Nirogi Mata Dr. Shriniwas Kashalikar
 
دليل لمستخدمي الرموز الرياضية
دليل لمستخدمي الرموز الرياضيةدليل لمستخدمي الرموز الرياضية
دليل لمستخدمي الرموز الرياضية
 
Nghe Nghiep Nguoi Me
Nghe Nghiep Nguoi MeNghe Nghiep Nguoi Me
Nghe Nghiep Nguoi Me
 
Carta Numeros
Carta NumerosCarta Numeros
Carta Numeros
 
ใบงาน3
ใบงาน3ใบงาน3
ใบงาน3
 
Cyber Bulling
Cyber BullingCyber Bulling
Cyber Bulling
 
Consigli Ai Naviganti Cerco Lavoro Biblioteca Cavriago
Consigli Ai Naviganti   Cerco Lavoro   Biblioteca CavriagoConsigli Ai Naviganti   Cerco Lavoro   Biblioteca Cavriago
Consigli Ai Naviganti Cerco Lavoro Biblioteca Cavriago
 
Artigo do publico 27 dez 2013
Artigo do publico   27 dez 2013Artigo do publico   27 dez 2013
Artigo do publico 27 dez 2013
 

Poängen med DDD

  • 1. Vad är poängen med domändriven design? Peter Backlund, Citerus AB peter.backlund@citerus.se 1
  • 2. Vad är poängen med domändriven design? Peter Backlund, Citerus AB peter.backlund@citerus.se 2
  • 4. Vad vi hade PeriodConfiguration getPeriodConfiguration(long personId,                                             long resourceGroupId,                                                   long bookersAccessCategoryId,                                             long from,                                             long to) • Utspridd logik • Svag eller beteendelösa typer • Svårt att studera, testa och förstå 4
  • 5. Vägen till en kraftfull modell • Domänexpert • Strukturera kunskap • Gemensamt språk 5
  • 6. "Ok, vi säger att en lägenhet vill boka tvättstuga 3 den 22:a oktober mellan 14.00 och 18.00..." 65
  • 7. Bokningsförfrågan public class Bokningsförfrågan implements ValueObject<Bokningsförfrågan> {     Bokare bokare;   Bokningsobjekt bokningsobjekt;      Pass pass;   ...   } 7
  • 8. "Man ska kunna ställa in så att om du har bokat tvättstugan exempelvis tre gånger den här månaden och alla bokningar är aktiva så ska det inte gå att boka en gång till förrän man har tagit bort nån bokning eller man har använt tvättiden, eller det blir en ny månad.” ”Det är viktigt därför att vi har upptäckt att folk bokar upp massor med pass och då ... vilket leder till att ... och ...” 85
  • 10. Struktur En av flera bokningsregler lyder: Ett bokningsobjekt ska kunna ställas in så att antalet bokningar per bokare per månad är begränsat till X st. En bokningsförfrågan tillåts om bokaren har färre än X aktiva bokningar av det bokningsobjektet under den månad då passet infaller, eller om ingen begränsning är satt. 10
  • 11. public class PerMånadPerBokareBegränsning implements Bokningsregel { @Override   public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {    [...]   }     } 11
  • 12. public class PerMånadPerBokareBegränsning implements Bokningsregel { @Override   public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {     Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();     Regelinställningar inställningar = bokningsobjekt.inställningar();     Integer antal = inställningar.perMånadPerBokare();              [...]   }    } 12
  • 13. public class PerMånadPerBokareBegränsning implements Bokningsregel { @Override   public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {     Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();     Regelinställningar inställningar = bokningsobjekt.inställningar();     Integer antal = inställningar.perMånadPerBokare();              if (ejAngivet(antal)) {      return true;     } else { [...]     }   } } 13
  • 14. public class PerMånadPerBokareBegränsning implements Bokningsregel { @Override   public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {     Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();     Regelinställningar inställningar = bokningsobjekt.inställningar();     Integer antal = inställningar.perMånadPerBokare();              if (ejAngivet(antal)) {      return true;     } else { Pass pass = bokningsförfrågan.pass();      Bokare bokare = bokningsförfrågan.bokare(); CalendarInterval passetsMånad = månadFörPasstart(pass);       [...]     }   } } 14
  • 15. public class PerMånadPerBokareBegränsning implements Bokningsregel { @Override   public boolean tillåter(Bokningsförfrågan bokningsförfrågan) {     Bokningsobjekt bokningsobjekt = bokningsförfrågan.bokningsobjekt();     Regelinställningar inställningar = bokningsobjekt.inställningar();     Integer antal = inställningar.perMånadPerBokare();              if (ejAngivet(antal)) {      return true;     } else { Pass pass = bokningsförfrågan.pass();      Bokare bokare = bokningsförfrågan.bokare(); CalendarInterval passetsMånad = månadFörPasstart(pass); List<Bokning> bokningarUnderMånad =  bokare.listaAktivaBokningar(bokningsobjekt, passetsMånad);       return bokningarUnderMånad.size() < antal;     }   } } 15
  • 16. En kraftfull modell public class Bokningsobjekt { List<CalendarDate> dagarMedLedigaPass(Bokare bokare, CalendarInterval intervall) {} List<Pass> ledigaPassUnderDag(Bokare bokare, CalendarDate dag) {} } 16
  • 17. private CalendarInterval månadFörPasstart(Pass pass) { TimePoint passtart = pass.somIntervall().start(); CalendarDate datumFörPassStart = passtart.calendarDate(TIDSZON); return datumFörPassStart.month(); } 17

Editor's Notes

  1. Hej jag heter ... och jag ska prata om po&amp;#xE4;ngen med dom&amp;#xE4;ndriven design och ber&amp;#xE4;tta om hur vi anv&amp;#xE4;nder det i mitt nuvarande uppdrag.
  2. Hej jag heter ... och jag ska prata om po&amp;#xE4;ngen med dom&amp;#xE4;ndriven design och ber&amp;#xE4;tta om hur vi anv&amp;#xE4;nder det i mitt nuvarande uppdrag.
  3. Med ordet &amp;#x201D;dom&amp;#xE4;n&amp;#x201D; i dom&amp;#xE4;ndriven design menas verksamhetsomr&amp;#xE5;de, det f&amp;#xF6;retaget eller myndigheten &amp;#xE4;gnar sig &amp;#xE5;t. Jag jobbar med ett stort och etablerat elektroniskt passersystem som styr vem som f&amp;#xE5;r komma in n&amp;#xE4;r och var. Det h&amp;#xE4;r systemet best&amp;#xE5;r av massor av moduler, varav en hanterar bokning, allts&amp;#xE5; tv&amp;#xE4;ttstugor, konferensrum, tennisbanor osv. Den h&amp;#xE4;r modulen stod i tur att genomg&amp;#xE5; en rad f&amp;#xF6;r&amp;#xE4;dringar, av olika anledningar.
  4. Koden som fanns var sv&amp;#xE5;r att jobba med. Aff&amp;#xE4;rslogiken var utspridd &amp;#xF6;ver alla lager, ibland i n&amp;#xE5;n if-sats i en jsp-sida, ibland i en SQL-sats och allting d&amp;#xE4;remellan. Mycket var duplicerat. Primitiva typer anv&amp;#xE4;ndes v&amp;#xE4;ldigt ofta, som ni kan se i den h&amp;#xE4;r autentiska metodsignaturen. De &amp;#x201D;dom&amp;#xE4;n&amp;#x201D;klasser som fanns hade i princip inget beteende eller inre validering, utan var rena databeh&amp;#xE5;llare. Det var transaktionsskript och blodfattig modell fullt ut. Det h&amp;#xE4;r var sv&amp;#xE5;rt att s&amp;#xE4;tta sig in i och sv&amp;#xE5;rt att testa p&amp;#xE5; ett meningsfullt s&amp;#xE4;tt. Vi ville f&amp;#xF6;r&amp;#xE4;ndra det h&amp;#xE4;r. Vi ville bygga en kraftfull modell som kunde l&amp;#xF6;sa dom&amp;#xE4;nens problem, allts&amp;#xE5; svara p&amp;#xE5; vem som f&amp;#xE5;r boka vad och n&amp;#xE4;r, p&amp;#xE5; ett robust och k&amp;#xE4;rnfullt s&amp;#xE4;tt.
  5. En av de viktigaste ingredienserna f&amp;#xF6;r att lyckas med DDD &amp;#xE4;r att man har tillg&amp;#xE5;ng till en dom&amp;#xE4;nexpert. DE &amp;#xE4;r en person som vet hur verksamheten fungerar och varf&amp;#xF6;r. Det kan handla om ren sakkunskap, produktens och aff&amp;#xE4;rsverksamhetens historiska utveckling och framtid, hur anv&amp;#xE4;ndare interagerar med produkten i vanliga situationer och liknande. En person som har l&amp;#xE5;ng erfarenhet av dom&amp;#xE4;nen. I v&amp;#xE5;rt fall fungerade v&amp;#xE5;r produkt&amp;#xE4;gare som dom&amp;#xE4;nexpert, vilket inte alls &amp;#xE4;r n&amp;#xF6;dv&amp;#xE4;ndigt med oftast &amp;#xE4;r bra. Det kan m&amp;#xF6;jligen leda till att PO tror sig kunna detaljstyra arbetet mer &amp;#xE4;n vad som &amp;#xE4;r nytttigt. Vi bj&amp;#xF6;d in DE till modelleringssessioner. Uppskattat. N&amp;#xE4;r man ska modellera tillsammans med DE &amp;#xE4;r det viktigt att ta vara p&amp;#xE5; tiden. Vara f&amp;#xF6;rberedd men inte f&amp;#xF6;rutfattad. L&amp;#xE4;s p&amp;#xE5;, skissa p&amp;#xE5; id&amp;#xE9;er, men var beredd att lyssna och ompr&amp;#xF6;va, och var noga med att inte k&amp;#xF6;ra &amp;#xF6;ver DE. Arbetet handlar om att &amp;#xF6;verf&amp;#xF6;ra kunskap fr&amp;#xE5;n DE till utvecklarna, och att strukturera den h&amp;#xE4;r kunskapen p&amp;#xE5; ett s&amp;#xE5;nt s&amp;#xE4;tt att vi kan skriva kod som fungerar p&amp;#xE5; samma s&amp;#xE4;tt. F&amp;#xF6;r att kunna &amp;#xF6;verf&amp;#xF6;ra och strukturera kunskap p&amp;#xE5; ett effektivt s&amp;#xE4;tt m&amp;#xE5;ste vi anv&amp;#xE4;nda ett gemensamt spr&amp;#xE5;k, ett spr&amp;#xE5;k som vi vill ska &amp;#xE5;terkomma i diskussioner mellan DE och utvecklare, utvecklare emellan och till och med inne i k&amp;#xE4;llkoden. Spr&amp;#xE5;ket bildas normalt som ett urval av etablerade termer och fackspr&amp;#xE5;k, men ibland kan man beh&amp;#xF6;va inf&amp;#xF6;ra nya begrepp, s&amp;#xE4;tta namn p&amp;#xE5; koncept som man pratar om under modelleringen.
  6. Den h&amp;#xE4;r typen av meningar var ofta avstamp n&amp;#xE4;r vi testade olika scenarier. Allt som ing&amp;#xE5;r n&amp;#xE4;r ett initiativ att boka n&amp;#xE5;got sker: vem, vad, n&amp;#xE4;r. Vi valde att inf&amp;#xF6;ra begreppet Bokningsf&amp;#xF6;rfr&amp;#xE5;gan.
  7. N&amp;#xE4;r vi inf&amp;#xF6;rde begreppet innebar det ocks&amp;#xE5; att vi skapade en klass med samma namn, med f&amp;#xE4;lt som svarar mot begreppets inneb&amp;#xF6;rd. ValueObject &amp;#xE4;r ett av flera designm&amp;#xF6;nster som hj&amp;#xE4;lper oss att karakt&amp;#xE4;risera v&amp;#xE5;ra klasser. Andra exempel &amp;#xE4;r entity, repository, factory och service. Ja, ni ser r&amp;#xE4;tt. Koden &amp;#xE4;r p&amp;#xE5; svenska. Jag antar att majoriteten av er rynkar p&amp;#xE5; n&amp;#xE4;san &amp;#xE5;t det, det hade jag sj&amp;#xE4;lv gjort f&amp;#xF6;r ett &amp;#xE5;r sedan. Jag har dock helt &amp;#xE4;ndrat uppfattning i den fr&amp;#xE5;gan och ser det numera som ett privilegium att kunnna skriva kod p&amp;#xE5; svenska. Det &amp;#xE4;r en naturlig konsekvens av att f&amp;#xF6;rs&amp;#xF6;ka anamma ett gemensamt spr&amp;#xE5;k. --- PAUS ---
  8. Nu t&amp;#xE4;nkte jag att vi skulle titta p&amp;#xE5; spr&amp;#xE5;k, modell och kod h&amp;#xE4;nger ihop i ett lite mer matnyttigt exempel. Under en modelleringssession tillsammans med DE skulle man kunna t&amp;#xE4;nka sig att det l&amp;#xE5;ter s&amp;#xE5;h&amp;#xE4;r (L&amp;#xC4;S).
  9. V&amp;#xE5;r uppgift &amp;#xE4;r nu att strukturera den h&amp;#xE4;r kunskapen f&amp;#xF6;r att kunna &amp;#xE5;stadkomma mjukvara i andra &amp;#xE4;ndan. Vi skissar p&amp;#xE5; whiteboard eller papper, f&amp;#xF6;rs&amp;#xF6;ker hitta m&amp;#xF6;nster, preciserar, generalisera, st&amp;#xE4;ller motfr&amp;#xE5;gor, provar scenarier, g&amp;#xF6;r saker explicita.
  10. N&amp;#xE4;r vi kommit en bit p&amp;#xE5; v&amp;#xE4;gen s&amp;#xE5; kan det se ut s&amp;#xE5;h&amp;#xE4;r, efter att ha experimenterat och modellerat, strukturerat kunskapen, kunna beskriva samma sak med v&amp;#xE4;l etablerade termer (L&amp;#xC4;S). Fortfarande &amp;#x201D;normal&amp;#x201D; svenska, fullt f&amp;#xF6;rst&amp;#xE5;eligt f&amp;#xF6;r en dom&amp;#xE4;nexpert. Det h&amp;#xE4;r &amp;#xE4;r kontaktytan mellan dom&amp;#xE4;nen och koden.