Wednesday, 4 April 2012

Domain Modelling Training Session 2

Last Friday saw the practical part of my Domain Modelling Training Session. This time the 'add to cart' functionality was in place, and it was the purpose of the rask to add the 'place order functionality', following the rules and guidelines set down in the last session. The specifications for this were:
  • Place an Order with an OrderLine for each book.
  • OrderLine must record price of book.
  • Order must record total book price in Cart.
  • Order must also record shipping cost of £2 + 50p per book.
  • Order must record grand total.
Another part of the test was for the developers to begin with the Domain unit tests, then move on to develop the Domain, then the Application Layer, then the UI.
Here are some examples of what was produced:

Domain Unit Test Code

public static Order Place(Cart cart)
    Order order = new Order();
    foreach (Book book in cart.Books)
        order._orderLines.Add(new OrderLine { Book = book, PricePaid = book.Price });
        order._booksTotal += book.Price;
    order._shippingCost = 2f + (cart.Books.Count * .5f);
    order._grandTotal = order._booksTotal + order._shippingCost;     
    return order;

Domain Code

public class OrderTest
    public void CanPlaceOrder()
        Cart cart = new Cart();
        Book book = new Book()
            Id = 1,
            AuthorName = "Robert C. Martin",
            Title = "Agile Principles, Patterns and Practices in C#",
            Price = 35.00f
        Order myOrder = Order.Place(cart);
        Assert.AreEqual(myOrder.OrderLines.Count, 1);
        Assert.AreEqual(myOrder.OrderLines[0].Book.Id, 1);
        Assert.AreEqual(myOrder.OrderLines[0].PricePaid, 35.00F);
        Assert.AreEqual(myOrder.BooksTotal, 35.00F);
        Assert.AreEqual(myOrder.GrandTotal, 37.50F);
        Assert.AreEqual(myOrder.ShippingCost, 2.5F);

Application Layer Code

public long Place()
    ICartRepository cartRepository = new CartRepository();
    IOrderRepository orderRepository = new OrderRepository();
    Cart cart = cartRepository.GetByUserName(Thread.CurrentPrincipal.Identity.Name)
    Order placedOrder = Order.Place(cart);

    using (ITransactionProvider transactionProvider = new TransactionProvider())

    return placedOrder.Id.Value;

UI code is simply one line calling this method.