Geeks With Blogs
.net alternatives by Michel Grootjans
Time for me to evaluate the progress on the original goals of our project. In januari, I started on a new project and set myself/the project a few goals. These goals were explicitly written down in a previous post. We've now finished phase 1 of the project, and I took the time to see what's left of my new year's resolutions.

What's the point?

I believe that you can only improve and learn new things when you deliberately set yourself explicit goals. Publishing these goals for all to see has been a major incentive for me to follow them up.

These are the goals I set for the project:

Overall

- readable, intent revealing software
- DRY, YAGNI, BOYSCOUT et all...
All in all, I think we've achieved this. What's even better, the team members started criticizing existing 'smelly' code with these principles in mind. I believe I planted a few good ideas that everyone will take to future projects

Entities

- Aggregate roots have an explicit interface
- No ID (I'm not sure if I can pull this one off with NHibernate)
- No (public) setters except for things like name, description, ...
- State based tests
- Testdata: take a look at NBuilder
No ID for entities was a challenge. At first all went well. Later on, NHibernate started complaining during specific queries that certain entities didn't contain an Id property. We didn't go into detail as to why that was. I intend to investigate this further, because I really liked the no-Id approach. We didn't get around to it yet.

No setter in properties caused a disturbance in the team. This meant that we needed a method each time an entity had to change state. I believe this effort has paid off, because our objects encapsulate their data and behavior much better this way (go look up the 'law' of Demeter for more info). Of course, as always, 'No setters' becomes 'Almost no setters'.

And we didn't get around to using NBuilder for test data. I'm not sure why, but we didn't. In the meantime, I met kilfour from QuickNet. I think QuickNet might be a good candidate to include in our test

Services

- almost no logic
- infrastructure: queries, mapping, ...
- hosted in spring.net
- Behaviour based tests
Services in this case were WCF services. Check on all four goals. Lucky for me 'almost no logic' contained 'almost'. It's always good to set goals, but if the goal is too expensive when there is an easier alternative that doesn't 'smell', I apply the KISS principle.

Controllers

- no logic
- only view concerns
- choice of view to render
- navigation (redirect)
- forward call to service
- Behavior based tests
- hosted in spring.net
Only a part of our application has a UI. The main part is web services, with a relatively small administration web site, built on asp.net mvc 2. Check on all goals here too. I might add that each view got it's own viewmodel. Thanks to automapper for making this so easy.

Repository

- only handles aggregate roots
- only the following methods: add/remove/query
Yep, only 1 repository, not 1 per aggregate root or (god forbid) 1 per entity. This repository contains only three methods:
void Add<T>(T t);
void Remove<T>(T t);
IQueryResult<T> Query(IQuery<T> query);

Add and Remove only accept IAggregateRoot entities.
Query() accepts only query objects.

Queries

- Separate query objects that get passed in the 'query' method of repository
- Preference in this order: LinqToNH, Criteria, HQL. Each query object can use any querying alternative from NHibernate
- Integration tested
Having separate query objects is something I'll try to apply on all upcoming projects. This way, we can have individual objects for each query that can be tested in isolation.

Security

- RhinoSecurity?
Nope, not needed at the moment. Security was not that big a concern... yet. This is phase 1 after all. That means phase 2 is coming up.

WCF

- Service hosting in Spring
Works OOB with spring.net.

Testing

- Heavy emphasis on readability
- Intent (test) Driven Development
- Fitnesse first (red), then unit test(R=>G=>R), integration test (R=>G=>R), Fitnesse green.
Check on all three goals. FitNesse first was a challenge, but it added a clarity to what we really wanted to accomplish in each story. In my opinion, FitNesse is a time saver when you're not sure how a feature should behave. It removes any ambiguity in the requirements before the implementation.

My original goal was to have the Product Owner write at least one FitNesse test per story to guide the team. This didn't work because the PO's workload didn't allow this. As a team, we decided to continue doing FitNesse up front.

Summary

First of all, we had a happy customer. In my opinion, this is what matters most. The customer was happy, because this design allowed us to have a flexible system which can easily adapt to changing requirements.

The team was happy too. We only had a small team of 4 people. Two of them had never heard of TDD, IoC, ORM, MVC, ... After a few weeks both became fans of this non-MSDN way of working. Retrospectives rule!
Posted on Monday, July 26, 2010 10:46 AM | Back to top


Comments on this post: Finshed the new project

# re: Finshed the new project
Requesting Gravatar...
2 suggestions for future goals:

1) stop using Spring.NET and use a more modern container (if only for the improved registration of components)
2) use Agatha for your WCF services :p

(i couldn't resist ;))
Left by Davy Brion on Jul 26, 2010 4:28 PM

Your comment:
 (will show your gravatar)


Copyright © Michel Grootjans | Powered by: GeeksWithBlogs.net