Loading ...
Global Do...
News & Politics
5
0
Try Now
Log In
Pricing
Informatik IT-Uddannelse og IT-Udvikling Domain Driven Design Informatik IT-Uddannelse og IT-Udvikling Morten Mertner Senior Consultant, Teknologisk Institut - Architect and Software Developer (C#) - Teacher - Speaker (conferences and gatherings) Certifications - MSCD.NET - MCT Open Source - Gentle.NET (object persistence framework / object-relational mapper) - MbUnit (unit test framework) Informatik IT-Uddannelse og IT-Udvikling Agenda Domain Driven Design - Introduction - Patterns - Entity and ValueObject - Repository - Specification - Extensions - Factory - Conclusion - Domain Models and SOA Informatik IT-Uddannelse og IT-Udvikling TransactionScript vs Domain Model Transaction Script - procedural - simple and easy to understand - minimal performance overhead - often results in cut & paste reuse (hard to maintain) - does not scale to complicated tasks Domain Model - logic organised in units that cooperate to solve business operations and rules - concepts in problem domain are modelled as classes - true object-orientation Informatik IT-Uddannelse og IT-Udvikling TransactionScript vs Domain Model Informatik IT-Uddannelse og IT-Udvikling Introduction Patterns - Entity - ValueObject - Repository - Specification Informatik IT-Uddannelse og IT-Udvikling DDD – Entity Entity - uniquely identifyable (has identity) - equality comparison uses identity (not attribute values) - usually extended longevity Examples - Product - Customer - Order Informatik IT-Uddannelse og IT-Udvikling Example: Order = Entity class Order { Customer customer; List<OrderLineItem> lineItems; public Order( Customer customer ) { this.customer = customer; lineItems = new List<OrderLineItems>(); } public void AddLineItem( OrderLineItem li ) { lineItems.Add(li); } public void RemoveLineItem( OrderLineItem li ) { lineItems.Remove(li); } public IList<OrderLineItem> LineItems{ get { return lineItems; } } public float GetTotalPrice() { float result = 0; foreach( OrderLineItem li in lineItems ) { result += li.Price; } return result; } } Informatik IT-Uddannelse og IT-Udvikling DDD – ValueObject ValueObject - no identity - equality comparison uses attribute values - describes entities - should be immutable Example - OrderLineItem Informatik IT-Uddannelse og IT-Udvikling Example: OrderLineItem = ValueObject class OrderLineItem { int quantity; Product product; float price; public OrderLineItem( Product p, int quantity, float price ) { this.product = p; this.quantity = quantity; this.price = price; } public int Quantity { get { return quantity; } } public Product Product { get { return product; } } public float Price { get { return price; } } } Informatik IT-Uddannelse og IT-Udvikling DDD – Entity & ValueObject Informatik IT-Uddannelse og IT-Udvikling DDD – Repository Repository - responsible for object persistence - interface similar to collection class - creates an illusion of all objects being in memory Example - CustomerRepository - ProductRepository - OrderRepository Informatik IT-Uddannelse og IT-Udvikling Repository public interface IRepository<T> { void Add( T newElement ); void Remove( T element ); void Remove( int oid ); T FindByOID( int oid ); IList<T> Select( ... ); } public class AbstractRepository<T> : IRepository<T> { // implemenation code } public class CustomerRepository : AbstractRepository<Customer> {} public class OrderRepository : AbstractRepository<Order> {} public class ProductRepository : AbstractRepository<Product> {} Informatik IT-Uddannelse og IT-Udvikling DDD – Repository Informatik IT-Uddannelse og IT-Udvikling DDD – Specification Specification - business rule (encapsulated in an object) Purpose - data query - validation Informatik IT-Uddannelse og IT-Udvikling DDD – Specification interface ISpecification<T> { bool IsSatisfiedBy( T domainObject ); } class GoldCustomerSpecification : ISpecification<Customer> { public bool IsSatisfiedBy( Customer customer ) { return customer.TotalOrderAmount > 10000; } } Informatik IT-Uddannelse og IT-Udvikling DDD – Repository + Specification public interface IRepository<T> { void Add( T newElement ); void Remove( T element ); void Remove( int oid ); T FindByOID( int oid ); IList<T> Select( ISpecification<T> spec ); } public class AbstractRepository<T> : IRepository<T> { // implemenation code } public class CustomerRepository : AbstractRepository<Customer> {} public class OrderRepository : AbstractRepository<Order> {} public class ProductRepository : AbstractRepository<Product> {} Informatik IT-Uddannelse og IT-Udvikling Specification with Persistence Support interface ISpecification<T> { bool IsSatisfiedBy( T domainObject ); bool HasQuerySupport { get; } string queryString { get; } // ADO.NET } interface ISpecification<T> { bool IsSatisfiedBy( T domainObject ); bool HasQuerySupport { get; } Expression Criteria { get; } // ORM (Gentle.NET 2.0) } Informatik IT-Uddannelse og IT-Udvikling RepositoryFactory RepositoryFactory - avoids coupling between entities in data access code - clean encapsulation of all database code - database provider independence (ADO.NET) - ORM independence Informatik IT-Uddannelse og IT-Udvikling RepositoryFactory public interface IRepositoryFactory { IRepository<T> GetRepository<T>( T entityType ); } public class RepositoryFactory { IRepository<T> GetRepository<T>( T entityType ) { return new GentleRepository<T>(); } } Informatik IT-Uddannelse og IT-Udvikling Usage // create new order Order order = new Order(); order.AddLineItem( new OrderLineItem( product, 5, 50.0 ) ); OrderRepository orderRepository = RepositoryFactory.GetRepository<Order>(); orderRepository.Add( order ); // find all gold customers CustomerRespository cr = RepositoryFactory.GetRepository<Customer>(); IList<Customer> goldies = cr.Select( new GoldCustomerSpecification() ); // check whether a given customer is a gold customer Customer customer = …; if( new GoldCustomerSpecification().IsSatisfiedBy( customer ) ) { … } Informatik IT-Uddannelse og IT-Udvikling Domain Models Advantages - provides sufficient abstraction to deal with complex problem domains - scales to very large code bases - common language between developers and domain experts - once mastered it is a powerful tool – you rarely develop any other way Disadvantages - mapping domain objects to a relational database is difficult and time- consuming (unless you use an ORM tool) - takes skill and effort to understand, experience to master Informatik IT-Uddannelse og IT-Udvikling Domain Models and SOA Informatik IT-Uddannelse og IT-Udvikling Resources Eric Evans Domain Driven Design http://domaindrivendesign.org/book/ Martin Fowler Patterns of Enterprise Application Architecture http://martinfowler.com/books.html#eaa Steve Eichert (blog) http://steve.emxsoftware.com/Domain+Driven+Design Kim Harding Christensen, EOS Informatik IT-Uddannelse og IT-Udvikling Implementation Gentle.NET 2.0 - open source ORM - working implementation ISpecification - ISpecification is called IFilter - IFilter supports Combine/Remove/Sort (both in-memory and data) - IObjectIdentity used to abstract object identifier (here we used int) Informatik IT-Uddannelse og IT-Udvikling Implementation Source Code http://www.mertner.com/svn/gentle/gentle/ SourceBranches/2.0.0/Gentle.Persistence/Client/Repository/*.cs http://www.mertner.com/fisheye Documentation http://www.mertner.com/confluence/display/Gentle/Design+Recommendations Informatik IT-Uddannelse og IT-Udvikling Questions? Informatik IT-Uddannelse og IT-Udvikling Thoughts & Unsolved Problems Transactions - transaction initiation and participation - cross-repository transactions - automatic enlisting Generics - make it difficult to put repository in base class - slightly more cumbersome than using non-generic classes RelationFilter - requires ability to modify not just the where-clause of queries