Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Domain Driven Design 101

38 822 vues

Publié le

Domain Driven Design (DDD) is a topic that's been gaining a lot of popularity in both the Java and .NET camps recently. Entities, value types, repositories, bounded contexts and anti-corruption layers -- find out what all the buzz is about, and how establishing a domain model can help you combat complexity in your code.

Richard Dingwall is a .NET developer and blogger with a passion for architecture and maintainable code.

He is currently working at Provoke Solutions as lead developer on a six-month project introducing test-driven development (TDD) and domain-driven design (DDD) to a large ASP.NET ERP system.

An hour-long talk given at Wellington .NET user group, Sept 23 2009.

Publié dans : Technologie, Business
  • DOWNLOAD FULL BOOKS, INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... 1.DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • wonderful, we need a DDD framework reduces complex, DDD Framework for Java: JdonFramework http://www.slideshare.net/banq/ddd-framework-for-java-jdonframework-2881760
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • very nice presentation, Richard.
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Thank you for sharing such insightful presentation on ddd.
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Domain Driven Design 101

  1. Domain Driven Design 101<br />
  2. Agenda<br />Why<br />Building blocks<br />Repositories, entities, specifications etc<br />Putting it to practice<br />Dependency injection<br />Persistence<br />Validation<br />Architecture<br />Challenges<br />When not to use DDD<br />Resources<br />
  3. Software is complicated<br />
  4. We solve complexity in software by distilling our problems<br />
  5. publicboolCanBook(Cargocargo, Voyagevoyage)<br />{<br />doublemaxBooking = voyage.Capacity * 1.1;<br />if (voyage.BookedCargoSize + cargo.Size &gt; maxBooking)<br />returnfalse;<br /> <br /> ...<br />}<br />publicboolCanBook(Cargocargo, Voyagevoyage)<br />{<br />if (!overbookingPolicy.IsAllowed(cargo, voyage))<br />returnfalse;<br /> <br /> ...<br />}<br />DDD is about making concepts explicit<br />
  6. Domain Model<br />
  7. Ubiquitous language<br />
  8. publicinterfaceISapService<br />{<br />doubleGetHourlyRate(intsapId);<br />}<br />û<br />A poor abstraction<br />publicinterfaceIPayrollService<br />{<br />doubleGetHourlyRate(Employeeemployee);<br />}<br />ü<br />Intention-revealing interfaces<br />
  9. publicclassEmployee<br />{<br />voidApplyForLeave(DateTime start,<br />DateTime end,<br />ILeaveService leaves)<br /> {<br /> ...<br /> }<br />}<br />
  10. Domain Expert<br />
  11. Entities<br />
  12. Value Types<br />
  13. publicclassEmployee : IEquatable&lt;Employee&gt;<br />{<br />publicbool Equals(Employee other)<br /> {<br />returnthis.Id.Equals(other.Id);<br /> }<br />}<br />Entities are the same if they have the same identity<br />publicclassPostalAddress : IEquatable&lt;PostalAddress&gt;<br />{<br />publicbool Equals(PostalAddress other)<br /> {<br />returnthis.Number.Equals(other.Number)<br /> && this.Street.Equals(other.Street)<br /> && this.PostCode.Equals(other.PostCode)<br /> && this.Country.Equals(other.Country);<br /> }<br />}<br />Value Types are the same if they have the same value<br />
  14. publicclassColour<br />{<br />publicint Red { get; privateset; }<br />publicint Green { get; privateset; }<br />publicint Blue { get; privateset; }<br /> <br />publicColour(int red, int green, int blue)<br /> {<br />this.Red = red;<br />this.Green = green;<br />this.Blue = blue;<br /> }<br /> <br />publicColourMixInTo(Colour other)<br /> {<br />returnnewColour(<br />Math.Avg(this.Red, other.Red),<br />Math.Avg(this.Green, other.Green), <br />Math.Avg(this.Blue, other.Blue));<br /> }<br />}<br />Value Types are immutable<br />
  15. Aggregates<br />
  16. Aggregate root<br />*<br />
  17. Repositories<br />
  18. publicinterfaceIEmployeeRepository<br />{<br />EmployeeGetById(int id);<br />void Add(Employeeemployee);<br />void Remove(Employeeemployee);<br /> <br />IEnumerable&lt;Employee&gt; GetStaffWorkingInRegion(Regionregion);<br />}<br />Repositories provide collection semantics and domain queries<br />
  19. Domain Services<br />
  20. publicinterfaceITripService<br />{<br />floatGetDrivingDistanceBetween(Location a, Location b);<br />}<br />
  21. Specifications<br />
  22. classGoldCustomerSpecification : ISpecification&lt;Customer&gt;<br />{<br />publicboolIsSatisfiedBy(Customer candidate)<br /> {<br />returncandidate.TotalPurchases &gt; 1000.0m;<br /> }<br />}<br /> <br />if (newGoldCustomerSpecification().IsSatisfiedBy(employee))<br />// apply special discount<br />Specifications encapsulate a single rule<br />
  23. Specifications can be used…<br />to construct objects<br />
  24. var spec = newPizzaSpecification()<br /> .BasedOn(newMargaritaPizzaSpecification())<br /> .WithThickCrust()<br /> .WithSwirl(Sauces.Bbq)<br /> .WithExtraCheese();<br /> <br />var pizza = newPizzaFactory().CreatePizzaFrom(spec);<br />Constructing objects according to a specification<br />
  25. Specifications can be used…<br />for querying<br />
  26. publicinterfaceICustomerRepository<br />{<br />IEnumerable&lt;Customer&gt; GetCustomersSatisfying(<br />ISpecification&lt;Customer&gt; spec);<br />}<br />vargoldCustomerSpec = newGoldCustomerSpecification();<br /> <br />var customers = this.customerRepository<br /> .GetCustomersSatisfying(goldCustomerSpec);<br />Querying for objects that match some specification<br />
  27. Anticorruption Layer<br />
  28. Your subsystem<br />Anti-corruption layer<br />Other subsystem<br />
  29. Any 3rd party system that I have to integrate with was written by a drunken monkey typing with his feet.<br />Oren Eini aka Ayende<br />
  30. Bounded Context<br />
  31. publicclassLead<br />{<br />publicIEnumerable&lt;Opportunity&gt; Opportunities { get; }<br />publicPerson Contact { get; }<br />}<br />publicclassClient<br />{<br />publicIEnumerable&lt;Invoice&gt; GetOutstandingInvoices();<br />publicAddressBillingAddress { get; }<br />publicIEnumerable&lt;Order&gt; PurchaseHistory { get; }<br />}<br />publicclassCustomer<br />{<br />publicIEnumerable&lt;Ticket&gt; Tickets { get; }<br />}<br />
  32. Dependency Injection<br />
  33. publicinterfaceINotificationService<br />{<br />void Notify(Employeeemployee, string message);<br />}<br />An interface defines the model<br />publicclassEmailNotificationService : INotificationService<br />{<br /> void Notify(Employeeemployee, string message)<br /> {<br />var message = newMailMessage(employee.Email, message);<br />this.smtpClient.Send(message);<br /> }<br />}<br />Far away, a concrete class satisfies it<br />
  34. publicclassLeaveService<br />{<br />privatereadonlyINotificationService notifications;<br /> <br />publicLeaveService(INotificationService notifications)<br /> {<br />this.notifications = notifications;<br /> }<br /> <br />publicvoidTakeLeave(Employeeemployee, DateTime start,<br />DateTime end)<br /> {<br />// do stuff<br /> <br />this.notifications.Notify(employee, &quot;Leave approved.&quot;);<br /> }<br />}<br />Dependencies are injected at runtime<br />
  35. Persistence Ignorance<br />
  36. …ordinary classes where you focus on the business problem at hand without adding stuff for infrastructure-related reasons… nothing else should be in the Domain Model.<br />
  37. publicclassCustomer<br />{<br />publicint Id { get; privateset; }<br />publicstringFirstName { get; set; }<br />publicstringLastName { get; set; }<br /> <br />publicIEnumerable&lt;Address&gt; Addresses { get; }<br />publicIEnumerable&lt;Order&gt; Orders { get; }<br /> <br />publicOrderCreateOrder(ShoppingCart cart)<br /> {<br /> ...<br /> }<br />}<br />Plain Old CLR Object (POCO)<br />
  38. [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName=&quot;AdventureWorksLTModel&quot;, Name=&quot;Customer&quot;)]<br /> [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]<br /> [global::System.Serializable()]<br />publicpartialclassCustomer : global::System.Data.Objects.DataClasses.EntityObject<br /> {<br /> [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]<br /> [global::System.Runtime.Serialization.DataMemberAttribute()]<br />publicintCustomerID<br /> {<br />get<br /> {<br />returnthis._CustomerID;<br /> }<br />set<br /> {<br />this.OnCustomerIDChanging(value);<br />this.ReportPropertyChanging(&quot;CustomerID&quot;);<br />this._CustomerID = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);<br />this.ReportPropertyChanged(&quot;CustomerID&quot;);<br />this.OnCustomerIDChanged();<br /> }<br /> }<br />privateint _CustomerID;<br />partialvoidOnCustomerIDChanging(int value);<br />partialvoidOnCustomerIDChanged();<br /> <br />This is not a POCO.<br />
  39. Architecture<br />
  40. Traditional Architecture<br />Presentation<br />Business Logic (BLL)<br />Infrastructure<br />Data Access (DAL)<br />
  41. Onion Architecture<br />User Interface<br />G<br />Application Services<br />M<br />Domain Services<br />Database<br />Domain Model<br />Services<br />File<br />system<br />Infrastructure<br />Tests<br />etc<br />
  42. Onion Architecture<br />EmployeeController<br />User Interface<br />G<br />Application Services<br />M<br />IEmailSender<br />Domain Services<br />Database<br />Domain Model<br />Services<br />File<br />system<br />Employee,<br />IEmployeeRepository<br />Infrastructure<br />Tests<br />SmtpEmailSender<br />etc<br />NHibernateEmployeeRepository<br />
  43. Validation<br />
  44. Validation Examples<br />Input validation<br />Is the first name filled in?<br />Is the e-mail address format valid?<br />Is the first name less than 255 characters long?<br />Is the chosen username available?<br />Is the password strong enough?<br />Is the requested book available, or already out on loan?<br />Is the customer eligible for this policy?<br />Business domain<br />
  45. publicclassPersonRepository : IPersonRepository<br />{<br />publicvoid Save(Person customer)<br /> {<br />if (!customer.IsValid())<br />thrownewException(...)<br /> }<br />}<br />validation and persistence anti-patterns<br />
  46. The golden rule for validation:<br />The Domain Model is always <br />in a valid state<br />
  47. publicclassNewUserFormValidator : AbstractValidator&lt;NewUserForm&gt;<br />{<br />IUsernameAvailabilityServiceusernameAvailabilityService;<br /> <br />publicNewUserFormValidator()<br /> {<br />RuleFor(f =&gt; f.Email).EmailAddress();<br /> <br />RuleFor(f =&gt; f.Username).NotEmpty().Length(1, 32)<br /> .WithMessage(&quot;Username must be between 1 and 32 characters&quot;);<br /> <br />RuleFor(f =&gt; f.Url).Must(s =&gt; Uri.IsWellFormedUriString(s))<br /> .Unless(f =&gt; String.IsNullOrEmpty(f.Url))<br /> .WithMessage(&quot;This doesn&apos;t look like a valid URL&quot;);<br /> <br />RuleFor(f =&gt; f.Username)<br /> .Must(s =&gt; this.usernameAvailabilityService.IsAvailable(s))<br /> .WithMessage(&quot;Username is already taken&quot;);<br /> }<br />}<br />separation of validation concerns with FluentValidation<br />
  48. Where validation fits<br />EmployeeController<br />User Interface<br />G<br />Application Services<br />M<br />IEmailSender<br />Domain Services<br />Database<br />Employee,<br />IEmployeeRepository<br />Domain Model<br />Services<br />NewUserForm,<br />NewUserFormValidator<br />IOverdraftLimitPolicy<br />File<br />system<br />Infrastructure<br />Tests<br />SmtpEmailSender<br />IUsernameAvailabilityService<br />etc<br />NHibernateEmployeeRepository<br />
  49. Making Roles Explicit<br />
  50. Challenges<br />
  51. When DDD isn’t appropriate<br />
  52. Benefits<br />
  53. Books<br />
  54. Links<br />Domain Driven Design mailing list<br />http://tech.groups.yahoo.com/group/domaindrivendesign/<br />ALT.NET mailing list<br />http://tech.groups.yahoo.com/group/altdotnet/<br />DDD Step By Step<br />http://dddstepbystep.com/<br />Domain Driven Design Quickly (e-book)<br />http://www.infoq.com/minibooks/domain-driven-design-quickly<br />
  55. Any fool can write code that a computer can understand. Good programmers write code that humans can understand.<br />Martin Fowler<br />
  56. Thanks for listening!<br />http://twitter.com/dingwallr<br />http://richarddingwall.name<br />rdingwall@gmail.com<br />

×