Generics and Anonymous Methods to the Rescue


If you are using an environment that supports generics (such as .NET 2.0), you can of course apply generics to the solution proposals discussed previously and gain slightly in explicitness, type safety, and performance. That goes, by the way, for most of the chapters discussed so far.

To take a small example, instead of this:

IList BrokenRulesRegardingPersistence {get;}


You could with generics use:

IList<IRule> BrokenRulesRegardingPersistence {get;}


Not a dramatic improvement or something we can't live without (as is shown throughout the book), but an improvement that will affect (again positively) many places in your code.

Another technique I have not had in the environments I've been working in most of the time is anonymous methods (similar to blocks or closures as it's called in other languages).

The idea is to be able to send a block of code as a parameter to a method, but the block of code can use variables that are in scope of the method that received the block.

Some people have discussed it as a way of implementing Specifications without creating new classes, although I think that means that you will lose some of the explicitness and clarity with the Specifications naming, which is a powerful feature of Specifications. Instead, I currently think of anonymous methods more as a good technique for providing variations to reusable assets. For example, you can inject part of the implementation of a method at will. It's a different way of thinking about customizability.

Just to give you a taste of the whole thing if you are new to the technique, let's combine generics and anonymous methods to a snippet we discussed previously and see if it can be improved. Do you remember the loop for seeing if a Customer needs to be invoiced? It looked like this:

//Customer public IList OrdersToInvoice(ReadyToInvoiceSpecification     specification) {     IList orders = _orderRepository.GetOrders(this);     IList result = new ArrayList();     foreach (Order o in orders)     {         if (specification.Test(o))             result.Add(o);     }     return result; }


Here it is again in a slightly modified version:

//Customer public List<Order>OrdersToInvoice(Predicate<Order>     readyToInvoicePredicate) {     List<Order> orders = _orderRepository.GetOrders(this);     return orders.FindAll(readyToInvoicePredicate); }


This time, the parameter is a predicate for if an Order can be invoiced or not. The call provides an anonymous method as the parameter. The call could be like this, assuming a very simple algorithm at this point in time:

c.OrdersToInvoice(delegate(Order o) {return o.Status == OrderStatus.ToBeInvoiced;});


That "Specification" or predicate is sent to the FindAll() method of the generic List for filtering out orders that can be invoiced.

At the time of this writing, it's still early for me regarding both generics and anonymous methods, but I'm sure they will make a huge difference regarding how I design in the foreseeable future. I'm not just talking about tiny things as in the examples above, but more like a mind shift.

But at the same time, they are just some more tools for the toolbox; they won't change everything, of course.




Applying Domain-Driven Design and Patterns(c) With Examples in C# and  .NET
Applying Domain-Driven Design and Patterns: With Examples in C# and .NET
ISBN: 0321268202
EAN: 2147483647
Year: 2006
Pages: 179
Authors: Jimmy Nilsson

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net