Friday, September 9, 2011

Repository Pattern

I have been doing some (a very little bit) 'on-the-side' development using the FMSC framework with an end goal of producing a fairly simple multi-platform trade and production game. If anyone is familiar with Eve-Online, this game is based on the market from that. This is really just an excuse to work with the framework, occupy my brain, and get some ideas going.

Anyway, while doing this I came across some discussions on the "Repository Pattern", EF 4.1 and when it is and is not required. Based on this I am thinking that the "Repository" layer could be removed.



To start with, I think the "repository project" that we have right now is still required at a basic level as this is where the DBContext lives, which is the way we interact with EF, but it is the individual Repository objects / Interfaces that I think could be removed and replaced with direct calls to the EF repository object.



Why the repository

Separation of concern – each repository instance is designed to separate the data access functions from the business logic functions. This is your general DAL/BL/UI separation, where the DAL in this case is the Repository.
Flexibility – the Repository Interface should allow you to swap out the underlying ORM with minimal impact


Why our repository implementation fails

1.a) The DBContext.Set() interface is itself a repository pattern. Business operations occur on the class instances exposed by the Set operation. E.g. DBContext.Set().add(itemInstance) will add an item to the database, exactly the same as ItemRepository.Add(itemInstance), but with a whole class layer being removed.

1.b) An intent of the repository layer was to ensure that all database operations were resolved before returning to the Business Layer, which prevented the business layer from essentially creating dynamic sql statements. However, it became apparent that the repository had to be flexible enough to provide the functionality that the BL requires, which required a lot of work (such as implementing a way to specify which children to load for an entity).

By adding this flexibility we then provided the BL with more ability to dictate the SQL that was generated, ultimately negating the purpose of the repository to begin with. The only benefit the repository now provided was that all queries would be resolved as soon as the repository was called, not when the service 'resolved' the query.

The cost of implementing this flexibility was also itself expensive, especially when EF itself provided this out of the box.

2) Being able to swap out one ORM for another (e.g. EF to nHibernate) would be a particularly amazing feature and is one of the Holy Grails of the repository pattern. However, as highlighted in a few blogs I read, a) how often does this happen (I'll slap whoever mentions CBH) and b) how much actual effort would it really save.

Due to the additional flexibility that we had to include to allow the repository to be an asset rather than a hindrance, I believe we are coupled closely enough with the underlying framework that changing ORMs is possible, but potentially more effort than is feasible. The potential payoff is there (one interface for EF or NH), but if we never get there then the repository is just a waste of effort.



Conclusion

For all future work on my "Market" game I will be using the EF Set() "repository" and will attempt to identify any areas where the repository layer is actually more suitable. If I find anything I'll blog about it.

Edit, I do actually think there is one area where the repository can provide a useful function, and thanks to Brian for bringing this up. The Non-Null Pattern (or whatever you want to call it) is a pretty useful pattern, one which can be helped tremendously by the repository. E.g., calling getSingle(query) on the repository can call the Set().FirstOrDefault(query) and if null return a blank T. However if you are working on the Set directly, you will need to check for the nulls in the BL and handle it appropriately. It may be possible to use extension methods to do this (actually, that might be a very good way of handling this, note to self), but the repository pattern does make it easy.

That is about the only real tangible benefit I can see of the repository however.

Need More Blogs

There has been a recent trend at work to try and get a bit more interaction and knowledge sharing between developers, and one of the ways this is being done is via internal Blogs.  Unfortunately it is pretty much just me writing these blogs, so I figured I'd throw my blogs open to a wider audience and start this blog up again. 

So beware the upcoming influx of blogs which may not all have an appropriate context (as they may expect knowledge of internal projects), but I'll attempt to ensure that all future blogs have as much context as they need.

Thursday, August 19, 2010

TFS 2010 ScrumForTeamSystem burndown chart modification

Well, I've been working on adding a total workload measure on our burndown chart, as well as a custom burndown for a subset of team members. A lot of the standard rules are not being followed by the team due to a reluctance to really embrace the process, so there are a lot of items moving between team members, and coming in and out of the sprint, so it has highlighted a few issues in the ScrumForTeamSystem charts.

Firstly, the default burndown filters on "not in" ( "done", "deleted", "descoped") SBTs. This works fine for the standard burndown, as "Done" items have 0 time remaining, so omitting them them simply improves the report performance.

However, adding the 'total workload' to the burndown incorrectly shows a 'drop' in workload when an item is completed, which is incorrect (we only what to drop the workload when an item is removed from the list). Simply adding 'done' items to the burndown list resolved this, so that was easy enough.

The second issue was somewhat more confusing until it 'clicked'. The initial capacity was vastly overstated, so I removed some items from the sprint. The team also decided to swap in some new items to the sprint as well (removing a few others).

After making the changes, I ran the burndown again, and noticed the workload, and work remaining, had risen, despite moving items out of the sprint.

Trying to figure this one out was a nightmare due to the complexity of the report query. In the end, it turns out that the burndown query was filtering incorrectly (possibly to try improve performance).

The way the query should work is that it returns the 'latest work item revision per day', and then checking if the work item is in the sprint (and/or assigned to a specific team member). The way it works was that it returned the 'latest work item revision in the sprint per day' which meant that the revision where it was still in the sprint was returned, so it was still included in the chart.

Once I realised what was going on (no mean feat the way the queries are designed, it took me half the day to figure it out), it was simple enough to fix.

1) Remove the filter that limits the revision list to the specified iteration (so we get all the revisions for each day)
2) add the iteration (and assigned to person) to the revision list
3) when aggregating the 'last revision item per day' items, filter by iteration and person.

All Fixed, now back to getting click-once working on TFS Build 2010 (we have a couple of custom requirements that will be the subject of another post.

Wednesday, August 18, 2010

On how I might be a hypocrite

I recently started looking at Windows Phone 7, and based on my previous anti-iphone/ipad rant I figured I would hate it. My main criticisms still apply (vendor lock-in, forced application registration, no multi-tasking), there is something about the architecture that I really do like.

I figure my excitement comes from the fact that MS make really good application development tools and frameworks, and as an MS developer for some time now, I am pretty confident that should I want to do something with my phone, I could probably do it. The thing I don't like is the need to register as a developer ($99/annum fee), but that does give you access to the MS store if you do decide to release any software. I guess if I was an apple person, I would feel the same way about the iPhone, so it makes me a big fat hypocrite.

Although it will be heavily criticised for the lack of multitasking, which will kill it until they bring it in (work on this is 'in progress' but won't make launch), I think the other application design features are pretty cool.

The way you interact with core services is very interesting. As each application uses isolated storage, it is not possible to create an application that will access the images on your phone directly. However, in order to list and select images from an application is as simple as invoking an image chooser service, that loads the built-in image browser/selector ('tombstoning' the parent application), and when complete, the parent application is restored. This effectively provides a number of core features within the phone accessible, with a consistent interface and usability.

Sure if the core services suck, then you are stuck with them, but it does improve phone security (you can't create a malicious app that will upload people's photos to the internet) and usability (to find a photo in app A is exactly the same as app B).

The other thing I really like is the messaging service that MS has developed for Windows Phone 7. There are core APIs that will allow web services to publish events to windows phone accounts (not individual phones). Once linked, your phone can receive these message much like push email notifications. These messages can update an application icon (to show that a new email has arrived on the home screen for example), or it can 'pop-up' a message on the screen no matter what you are doing, and you can choose to action the pop-up (loading the appropriate app), or ignore it and continue working. This sort of thing has been around a while, for example when a new sms comes through on my nokia I get a popup that i can action to load the sms. However the scope of this service is such that it can be used for any notification via web services.

An example of how this could be cool is a turn-based multiplayer game where each player receives a notification message when it is your turn. The game does not need to have each player running the app at the same time, each player can open the game, make a move, and the game server will issue the update to each other player. The players can receive the notification and view the move (loading the game), or ignore it until they have the opportunity to load the game in their own time. When it is a particular player's turn, they can also be notified by a separate message letting them know that the rest of the players are waiting.

Anyway, I admit it, I am somewhat excited by Windows Phone 7 and will be playing with the beta development tools. Early next year I will be due for a new phone, and by then there should be a couple of windows phone 7 devices out, so it'll be interesting to see whether android, wp7, or nokia will be my poison this time.

Tuesday, August 17, 2010

VMWare Server + Windows 7 = RAM hog

I've been annoyed in the past with installing Dev tools on my PC and having so many new services slowing my gaming down that I spend hours killing services just to get things back to normal again.

So I figured I would try creating VMWare virtual machines for the dev tools, and just run the images when I want to do some development. It also lets my try a few things that I hadn't had the opportunity to explore, such as Windows Server set up and configuration. The plan was to set up a Windows Server 2008 R2 system with TFS (Team Foundation Server) to track a mini project, and a Windows 7 development PC to do the work on.

Installing the base OSs was straight forward, and the individual VMs ran well enough with 1gb ram assigned to them. TFS stand-alone (TFS application and database on the one server) requires 2gb ram before it will even install however, which begain the problems. Adding the extra ram took a reboot, TFS installed, and everything seemed to be ok. Time to boot the Dev machine.

I figured i'd be good to go with them both running, 3gb for the VMs, 1gb for my host system (win7 64bit, 4gb ram). Unfortunately running both at once brought my system to a grinding halt. Fail. Ok, so try drop the server image to 1.5gb, slightly better, but not much.

Finally, dropping both systems to 1GB allowed them to run in tandem, but unfortunately the TFS image ran too slowly to be of much use. Fail.

In the end I decided to drop the TFS server, and just stick to a 2gb development image. It works well, I am just a little disappointed because I was hoping to use the TFS instance to help plan the mini-project, and having a plan in place might help with my procrastination.

Wednesday, July 28, 2010

Consumption vs Production

or why I think iPads are cool, but i'll never buy one...

I often have discussions with people on why I don't want an iPhone. It boils down to their 'restrictive' nature, and it made me think about why I would probably never own one. For instance, to listen to music or watch video you must use iTunes to sync the media to your device, in a format supported by iTunes. All the apps must be approved by apple, can be revoked at any time, and must be purchased via iTunes.

While the above reason is a major reason for my dislike, it is that to me the devices are all about consumption rather than production that really turns me off the devices. Sure you can twitter and facebook on your iPhone and iPad, but to write this blog would be a PITA (unless you used an iPad apple keyboard $$$). Granted there are some things that it works really well for (apparently there is at least one amazing painting app on the iPad), but in general you can only effectively use it for watching video, browsing the internet, and playing games.

I don't know why I have such a problem with this, perhaps it is the fact that I enjoy tinkering with things rather than watching youtube and facebooking all day. My laptop can do that, and a whole lot more. I can appreciate why people like these devices, they do some cool things, but their limitations would be a constant reminder that I can't actually DO anything with the devices.

YMMV

Moving up...?

As a software developer, one that loves what I do, there is not a lot of room to move upward in a large corporation. Developers are seen as just a resource, and it is the project managers, business analysts, and of course the salespeople who get all the recognition and big raises. The only way to move up in a technical position is to become an architect, which requires a significant amount of out-of-work effort in personal development to keep up with technologies and tools.

My current project was a step in the managerial field as a technical team leader. I have a strong hand in the design and architecture of the application, but in a very flat team structure where the entire team was responsible for the project planning (it was an Agile project). The first couple of months was very rewarding, with a lot of technical and architectural input in conjunction with the team lead responsibilities. The last few months were quite the opposite, with a strong focus on team and time management, with very little development effort aside from resolving quality issues. The main reason for this was that one of the developers was not very focused and took a significant amount of coaxing to follow the correct processes, and another one was dedicated, but not a very good developer. The best developer was new to the company and the customer site, but proved his capabilities very quickly.

When the project was coming near to an end, I put some feelers out for what I would be doing next. As it turned out, there was a new project that was trying to get started. Within a week I became the prime candidate as a Team Leader role on the project, and within two weeks I had been interviewed by the client and was just waiting on them to sign a resource contract before I was officially moving on to the project.

So, on Monday I will be a Team Lead on a new project, for a new client, but will be a team leader only, no development. The project is significantly larger than any I have worked on before, but is a strange mix of developers from both the client and my company, where we are just providing resources to fill positions, rather than running the project. This means i'll be managing a mostly internal team (they have also sourced contractors from elsewhere) as an external resource, which will be challenging.

All in all, I am looking forward to the change, but I am going to miss development a lot. Hopefully I enjoy the role enough that the lack of development doesn't destroy my work drive. Unfortunately I won't be seeing a raise or promotion based on this role until this time next year (unless I really push for it) as the yearly reviews are all over. Should this project go really well, it will bode very well for future work at the client, and hopefully I'll get some sort of recognition.