Developing SEE Infrastructure: Take a ride with me and practice your TDD

I’m having 1-on-1 coaching with Roy Osherove on TDD coming up in the following 2-3 weeks. My goal is to practice real TDD work process to determine if our department can benefit from this developing methodology (or as a design tool).


I’ve read a big bunch of articles and blogs (Jeremy D. Miller, Sam Gentile, Scott Bellware, Roy Osherove and others) about TDD and even practiced it for a bit during the last two years, but to be sincere, it wasn’t a real Test Driven Development. I stopped TDD-ing in the middle and moved back to write-with-haste, switched to TDD and so forth. I was lazy and I had no one to guide me through. I had to “guess” the right process and to read a big set of articles to see if I’m on the right track. I was lacking of some good feedback.


This 1-on-1 with Roy should give me a clear insight about the process and immediate feedback. If the process will prove itself, we’ll arrange a 3 days course for my department and try to fit TDD to our development process (where and how I’m still not sure, but I’ve got the feeling that I’ll be smarter in a few weeks).


What is SEE Infrastructure all about ?


SEE stand for: Simple Expression Engine which I’ve wrote about before.


I came up with SEE as I wanted to SEE what sort of filter the GUI requests from our Data Services.


I’ll give you an example for a client’s request and a solution based on our old infrastructure and how SEE changed the picture.


Example:


Let’s imagine we have a screen with one GridView. Our goal is to show all the (1) active orders (2) from today with (3) price bigger than 1000 NIS. It should be easy as counting 1,2,3 right ?


– OLD –


With our old infrastructure the code will look something like this:


(1) Orders.aspx:


OrdersFilter filter = new OrdersFilter();
filter.IsActive = true;
filter.Date = DateTime.Today;
filter.Price = 1000;

EntityCollection<Order> orders = OrdersService.Instance.Get(filter);
// … bind orders to our GridView …


(2) OrdersDal.cs:


in our Data Access Object for the Orders entity, we’re required to override a method which builds the dynamic SQL based on the given filter:


if (this.Filter.IsActive != null)
{
   query.Append(” AND Orders.IsActive = @IsActive”);
   paramaters.Add(DbServices.CreateParameter(“IsActive”, SqlDbType.Bit, this.Filter.IsActive));
}

if (this.Filter.Date != null)
{
   query.Append(” AND Orders.OrderDate = @Date”);
   paramaters.Add(DbServices.CreateParameter(“Date”, SqlDbType.DateTime, this.Filter.Date));
}

if (this.Filter.Price != null)
{
   query.Append(” AND Orders.Price > @Price”);
   paramaters.Add(DbServices.CreateParameter(“Price”, SqlDbType.Double, this.Filter.Price));
}


Now, look at the 2 lines marked in red. The filter at the GUI sent Price = 1000 while the DAL object looks for Price > 1000 (remember, this is the client’s request).


Not only we’ve got a mismatch, the coding wasn’t trivial nor “easy”. We had to know(=remember) what method to override at our OrdersDal.


– New –


Orders.aspx:


FilterExpression filter = new FilterExpression();
filter.Where(
   Where.EqualTo(Order.Field.IsActive, true),
   Operator.And(),
   Where.EqualTo(Order.Field.Date, DateTime.Today),
   Operator.And(),
   Where.GreaterThan(Order.Field.Price, 1000)
);

EntityCollection<Order> orders = OrdersService.Instance.GetByExpression(filter);
// … bind orders to our GridView …



That’s it. No mismatch – the GUI programmer can now see exactly what results the Orders Service will return and no need to look at OrdersDal.
Coding was short and fun.



I thought that this small but important infrastructure will be a nice platform to practice a “Real-World” work with TDD. The infrastructure at its current form is working quite well so I know how to API should look in general and what are my “big” problems (Mapping, Resolving db function names and a few more).


Is SEE revolutionary ?


Hardly!
Expressions like languages are all over the place lately:



  1. LINQ – to be honest, this is a really great query language but it ruined my Visual Studio .Net 2005!! The product requires some installation that simply is a disaster for a developer station.
  2. HQL – Nhibernate. This is actually very nice but I get no errors during writing.
  3. eSql – Looks great. is it safe for production? I’m not so sure… anyway, it’s all with C# 3.0 and suffers from symptom (1).

I can add additional 2-3 infrastructures to the list but you get the picture.  


So why do I\you still need SEE for ?


SEE is an home-made infrastructure which was developed by the KISS (keep it simple, stupid) principle. I know that there are many folks out there who still write\generate custom Data Access Objects. Integrating SEE in your custom DAO objects will be very simple as the infrastructure gives a solution to a very narrow problem domain. There is no need to learn a new “quotation marks prisoner” language. The developer can enjoy the VS.NET IntelliSense and as you could see in my previous example, the API is very easy to understand.


Moving toward one of the other languages\technologies can take some time as the learning curve can be quite high.

You could SEE with a very small time investment by your side.



Where do you come along ?


I will upload any code I’ll write during this coaching lessons so you can see our progress, bit after bit. In addition, I’m going to write a prolonged post after each lesson, to share with you my insights. This is the interesting part though – my infrastructure will change according to your requests (well, some of them anyway, and only the “good” and “simple” ones ;)). Feel free to suggest new features or to change method\classes names\relations. This will able me to practice changes to our SEE infrastructure as part of the TDD practice.


I hope that we’ll enjoy the process and learn new things on the way,
Oren.

Oren Ellenbogen

5 thoughts on “Developing SEE Infrastructure: Take a ride with me and practice your TDD

  1. Looks like a great tool, I can SEE why you like it so much. And I agree this is a great candidate for starting TDD with…

    We are using something very similar in our infrastructure so I can vouch for the success of this approach.

    The one thing that interests me here is that looking at the new code, I don’t see the need for either the OrdersFilter or the OrdersService classes. If you replace these classes with classes named "Filter" and "Service" the code remains logical (well, the GetByExpression method will have to be generic to return Order). What I’m saying is that "Order" seems to be the only class uniquely relevant to this piece of code – and by getting yourself to a point where the word "Order" will appear in one class only you are getting closer to encapsulation and abstraction of the whole filtering process…
    (I’ve done this a couple of weeks ago…)

  2. nothing to add except that i hope you will get some new ideas …
    I can not wait to read your future thoughs and feelings from this coaching…
    Enjoy mate!

  3. @Yoni,

    I actually have only one FilterExpression (and not [Entity]Filter as before). I simply forgot to write it as I’m writing the code on-the-fly, during the post. I fixed the example in the post.

    In addition, I have one abstract DataAccessObject which knows how to work with every FilterExpression. Each entity in my domain inherit from this object and implement the required stuff.

    Thanks for the heads-up.

    @Dror,
    I can’t wait either. Thanks.

  4. about the "Is SEE revolutionary" paragraph.

    LINQ is the only one of the mentioned to be compared to SEE.
    HQL and eSQL (OQL, too) are both addressing a different problem, known as the "Impendence Mismatch", meaning the different between object mapping (in the app domain) and relations mapping (in the DB domain). both HQL and eSQL (and OQL too, for the matter) are text based, and are supposed to be evaluated by the DB engine (OQL) or some middle mapping tool (HQL and eSQL). So as you can write text-based late-bound queries in your code, using eSQL or HQL, you can also use "old fashioned" SQL for the matter. SSE gives you the ability to write your queries in an early bound fashion, as LINQ does, thus helping the developer to narrow down the possible mistakes road, without the need of specialized Filters and Dals to do so.

  5. Ken – your reply is right on the money and nicely put. My original purpose was the make it clear as possible – SEE is a different way to do the same as already possible today, but it has its own strengths.

    Thanks mate.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>