The intersection of technology and leadership

Category: Development (Page 17 of 18)

The Benefits of Should and Following BDD

On one project I’ve been on, all the tests began with the word “should”. Though not necessarily taking on full on BDD using anything like NBehave or JBehave, I think the simple effect of reframing tests using the word “should” worked wonders on this particular project.

We had quite a lot of people pass through the project over a year and a half, so I found it interesting to see what impact it had on tests. I observed that:

  • People focused on understanding intent first, and followed through with how it was implemented.
  • People had better conversations around differences (the test name said it should be doing this, and it’s actually doing this. They asked questions like, “Is the name of this test wrong, or is the test incorrectly implemented?”
  • The statement is not as strong as assert or must so I felt people could challenge it more, leading to better quality conversations. “I though the domain was supposed to be like this, and the test and the code does this – Am I misunderstanding something?”

I think this subtle focus brought many qualitative benefits that I think a lot of projects could benefit from.

Software Architects Of Today

Shouldn’t be sitting in ivory towers dispensing design documents or ideas with no basis of reality.

They should be coding. They should hang around to see how their decisions pan out.

They should be hunting down smells, listening to the team about painful areas, thinking about how to turn them around. They should work with the team to co-ordinate a strategy for redesign or a series of refactoring to turn complex code into simpler designs.

They should be sharing their experience in collaborative ways with the team to create several design choices, to clarify the pros and cons and to refine them to a best choice.

They should still be looking at the bigger picture, and always looking for ways to share that big picture. Part of it might be an XP Metaphor (or the Shared Vision). It might come out looking like an architecture diagram.

I’m sure of missed some things, and I know for a fact, most software architects can’t meet even these. Fortunately I get to work with many who do.

UK November Away Day

I’ve been lucky enough to attend two of Thoughtworks‘ Away Days over the last month. Most recently I attended the UK Away Day this weekend that provided a great opportunity to catch up with some people and generate some new ideas. I’d write up more about the Indian Away Day I’d attended two weeks prior, but running a two week training course almost immediately has taken away my time to reflect and my memory’s a little foggy these days.

Here’s an overview of the sessions that I attended:

  • A Lessons Learned session applying Ruby on Rails – An interesting session presented by Paul Ingles and George Malamadis about their approach to building a fully functional website with some of the pitfalls. I love these sorts of sessions as you get the insight into the decision making processes with talk about the constraints and thinking that pushed patterns into the direction of the end result. Really nice and a great topic to start leading into the Meta Programming session later than evening.
  • The Space Within – Hosted by the very calm Manoj Ramachadran who ran through a number of exercises to help improve the “quiet” times in our lives and give us an ability to become more effective. I found this interesting as it gave me insights into other methods to try.
  • Features of C#3.0 – Presented by Troy Gould and a great statement opening it along the lines of C#3.0 is included in .Net 3.5. How confusing is that? An interesting code example comparison by comparison of features new to C#3.0 introduced to support Linq. I think pretty much everyone was thinking how these features could be used effectively, and where they would be more likely (ab)used.
  • Case Study of a Consulting only session – An ever excitable and interesting co-presentation with Luke Barrett and one of our clients where the focus wasn’t directly about delivering working software, but focusing on delivering value even earlier by clarifying a business case and helping evaluate its feasibility. I enjoyed hearing the application of the same lo-fi techniques and methods bringing value in a different space for once.
  • Meta Programming – A fun session running through features of Meta Programming in Ruby by Farooq Ali and Julie Yaunches. I really enjoyed this session, and glad I could attend this since I’ve had the pleasure of working in the same room with both of these people and they’re passion for Ruby really shone throughout the presentation. They reminded me of the power language gives, and definitely helped me refine some thoughts I’d been having about the environment or approach needed to pull this off successfully.

I had a great time catching up with loads of people and had plenty of fun after the conference gathering at Sway.

Test Driven Development Requires Less Debugging

I’ve been writing Test Driven code for the last few years and it’s become a natural part of the way I write most code. It was only recently that a co-worker, relatively new to Test Driven Development commented on something I’d never taken notice of.

We were in the midst of some work and ended up with some strange behaviour when we clicked through our application. We inspected the tests to ensure all the tests looked like they were working, and then proceeded to fire up the debugger. My pair then commented, “I’ve noticed you rarely use the debugger when you Test Drive your code”, and you know, he was very correct.

I wouldn’t never say you never need to debug during Test Driven Development (especially when it comes to diagnosing system state and certain triggers) but you definitely spend significantly less of your time in debug mode as you’re verifying bits of your code along the way. And that’s certainly a better place to be.

Well Finally…

I’ve seen several projects use FIT and thankfully I didn’t hang around on them too long. I’ve not been a huge fan of FIT (though I will admit it has its purposes). Thanks to James Shore for writing a blog entry about when not to use FIT (and hey, it’s really not that often you should be!). He’s also very humble enough to admit his mistake around promoting it with his articles on “executable specifications”.

If you’re a FIT fan, have a good read of this.

Seeking out project smells

Our project has had enough time lately to really focus on some good clean up around the codebase. The project has been under major development for well over a year with plenty of people having worked on it so I find it an interesting experience to see from a high level how things are. FxCop helps us to a certain degree but here’s some very simple metrics I’ve been using to help draw out things to fix:

  • ToDo‘s indicating unfinished tasks or notes made by other people. Each represents a signpost that forces people to pause or question what’s there. Each should be considered individually and should be completed, or deleted where possible. Resharper makes it even easier to find them with their TODO Explorer. Our project had a total of five of them.
  • Ignored tests are large potential sources of problems, indicating that code could be untested, or a test is not providing the feedback that it should be. There tests should be rewritten, implemented or deleted if they are no longer needed so people don’t need to maintain them. Our project’s grand total… 12 out of 2390.
  • Commented code is an obvious code smell, often created by many different reasons (the trick, like the above items are to find out why they’re there). Sometimes the code surrounding the comment may not be readable enough for someone to follow through and that’s easy to fix by applying a variety of refactoring techniques. Other times, commented code may be out of date and is left there because someone wanted to show how something is different – I would use refactoring such as extract method or variable, rename method or variable to help give additional context to get rid of the old code as it’s more important for people to understand what is working now more so than what it is. As a last resort, comments may be there to help explain to other developers why something is there and may be a pragmatic solution to an otherwise convoluted context. These should be exceptional and I would be greatly concerned if these were everywhere. My metric for this was very high, at 6730 lines out of 173122 lines of code although I think most of them are the .Net designer generated code for Winforms and ASP.Net pages.

Overall I was surprised at how little there was to fix with these considering how quickly the codebase has been moving and how many developers have been involved. It’s great to see everyone living the values and I think it shows in the quality of the software.

Events, Reflection and how they don’t work in C#

Although the .Net reflection APIs make some tasks easier, we’ve found recently that those related to events and their delegates have been fairly poorly designed. Our task was very simple: dynamically manipulate the event handlers attached to a set of events.

It’s easy enough to get a declaration about an event of some sort using code like:

EventInfo infoAboutEvent = someObject.GetType().GetEvent("MyEvent"); 

Given your EventInfo class it’s easy to add an a new event handler. Unfortunately going the other way around ended up much harder. Unlike things like FieldInfo that give you direct access to get the field instance from the object using GetValue(owner), finding the event field isn’t as easy. First we had to look at all the fields, and filtered out things that looked like a Delegate so we could do some useful things with them, like finding out what subscribers were hooked up to our event.

Our ultimate goal of being able to dynamically remove EventHandlers at runtime further ran into problems when we were trying to unhook methods from private events. The result of trying to unhook a handler from a private event via the EventInfo.RemoveEventHandler method results in an InvalidOperationException with a message of “Cannot remove the event handler since no public remove method exists for the event.”

One more simple use of reflection and soon we were able to automatically unhook a variety of delegates from our events regardless of their access mechanism (although using code that wasn’t as nice as we wanted). A few refactorings later and we ended up with something actually quite useful in the end.

ReflectUtil.RemoveEventHandlersFrom(
 delegate(Delegate subject) { return subject.Method.Name.StartsWith("On"); }, 
  objectWithEvent);

And here’s the class that we ended up with. Although I can’t recommend people use reflection lightly, if you need to delve into the world of reflection with events, I hope you find this example useful.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public sealed class ReflectUtil
{
  private static BindingFlags PrivatePublicStaticInstance 
    = BindingFlags.NonPublic | BindingFlags.Public |
      BindingFlags.Instance | BindingFlags.Static;

  public delegate bool MatchesOnDelegate(Delegate subject);

  public static void RemoveEventHandlersFrom(
    MatchesOnDelegate matchesOnDelegate, params object[] objectsWithEvents)
  {
    foreach (object owningObject in objectsWithEvents)
    {
      foreach (DelegateInfo eventFromOwningObject in GetDelegates(owningObject))
      {
        foreach (Delegate subscriber in eventFromOwningObject.GetInvocationList())
        {
          if (matchesOnDelegate(subscriber))
          {
            EventInfo theEvent = eventFromOwningObject.GetEventInfo();
            RemoveSubscriberEvenIfItsPrivate(theEvent, owningObject, subscriber);
          }
        }
      }
    }
  }

  // You can use eventInfo.RemoveEventHandler(owningObject, subscriber) 
  // unless it's a private delegate
  private static void RemoveSubscriberEvenIfItsPrivate(
    EventInfo eventInfo, object owningObject, Delegate subscriber)
  {
    MethodInfo privateRemoveMethod = eventInfo.GetRemoveMethod(true);
    privateRemoveMethod.Invoke(owningObject,
                               PrivatePublicStaticInstance, null, 
                               new object[] {subscriber}, CultureInfo.CurrentCulture);
  }

  private static DelegateInfo[] GetDelegates(object owningObject)
  {
    List delegates = new List();
    FieldInfo[] allPotentialEvents = owningObject.GetType()
      .GetFields(PrivatePublicStaticInstance);
    foreach (FieldInfo privateFieldInfo in allPotentialEvents)
    {
      Delegate eventFromOwningObject = privateFieldInfo.GetValue(owningObject) 
        as Delegate;
      if (eventFromOwningObject != null)
      {
        delegates.Add(new DelegateInfo(eventFromOwningObject, privateFieldInfo, 
          owningObject));
      }
    }
    return delegates.ToArray();
  }

  private class DelegateInfo
  {
    private readonly Delegate delegateInformation;
    private readonly FieldInfo fieldInfo;
    private readonly object owningObject;

    public DelegateInfo(Delegate delegateInformation, FieldInfo fieldInfo, 
      object owningObject)
    {
      this.delegateInformation = delegateInformation;
      this.fieldInfo = fieldInfo;
      this.owningObject = owningObject;
    }

    public Delegate[] GetInvocationList()
    {
      return delegateInformation.GetInvocationList();
    }

    public EventInfo GetEventInfo()
    {
      return owningObject.GetType().GetEvent(fieldInfo.Name, 
        PrivatePublicStaticInstance);
    }
  }
}

Upgrading from NHibernate 1.0.2 to 1.2.0.GA Experience Report

We recently upgraded to the latest version of NHibernate to make use of many of its new features. There are plenty of good reasons to upgrade including proper support of .Net 2.0, bug fixes, multi queries, new database dialects (including SQL Server 2005) and the ability to use generic types. We anticipated a few issues upgrading NHibernate, and though not the hardest upgrade ever, we did end up with a few more issues than expected. Here’s our experience upgrading to the latest version.

Things they warned you about

The NHibernate guys did a fantastic job writing their migration guide. They warned us that it wasn’t just simply a drop-in replacement and included a number of breaking API changes. Things that we found easy and had been documented included:

  • Updating our XML files from urn:nhibernate-mapping-2.0 to urn:nhibernate-mapping-2.2
  • Replacing outer-join="true" to fetch="join" and outer-join="false" to fetch="select"
  • Adding default-lazy="false" to each mapping file to deal with the change in default lazy loading behaviour
  • The HSQL count had been upgraded from an int type to a long type and our code had to cast it to the correct types
  • Deprecation of the CreateSQLQuery with parameters changed to ISQLQuery(String)

Things not on the label

  • Strange behaviour around the nosetter.camelcase access strategy – We had a property exposing a primitive type (string) of a more complex type, given the same field name and we kept getting a null result. It looked like it was trying to set the field using the type of the get property, even though the set should have been using the more complex user type. We fixed this by changing our mappings to field.camelcase instead of using the nosetter.camelcase.
  • SQL statement logging has changed – Our application listens very carefully to the Log4Net output that NHibernate generates, capturing each SQL statement and its parameters. Previous versions of NHibernate used to log their parameter values separately from their SQL statements, instead they are now logged on the single line. Thankfully our change was contained to two very small classes.
  • Replacing IClassPersister with IEntityPersister – We had to add a different constructor to our custom user types (also different from the current documentation), with a signature of PersistentClass model, ICacheConcurrencyStrategy cache, ISessionFactory required, IMapping mapping. Additionally we had to implement the new property Factory that came along with this interface. Now I had no idea where ISessionFactoryImplementor came from. Looking at the code, they had cast ISessionFactory in their constructor, and then returned that when the property Factory was called. It is a small inconsistency in their API that we ended up having to duplicate. This would be a problem if you ended up writing your own ISessionFactory but thankfully we haven’t done that ourselves. There were plenty more methods that we had to implement though none of them were actually very insteresting for the things that we had to do. Our solution: Cast ISessionFactory to ISessionFactoryImplementor and store it in the constructor just to be returned in the property.
  • IUserType Classes Disappearing – They had warned you that IUserType had moved into another namespace though I wasn’t quite clear what you had to do if you were using one of the old versions. In the end new Int16SqlType() is replaced by SqlTypeFactory.Int16, new Int32SqlType() by SqlTypeFactory.Int32, new Int64SqlType() by SqlTypeFactory.Int64, and new GuidSqlType() by SqlTypeFactory.Guid. I’m guessing it would be the same for any other IUserTypes you may be using.
  • IUserType New Methods – Four new methods appeared on the interface, GetHashCode, Replace, Assemble, Disassemble. Implementing GetHashCode we ended up delegating to our object, replace we delegated to using disassmemble then assemble, and implemented assemble and disassemble using DeepCopy, emulating what NHibernate Types do. It wasn’t really clear to me from documentation or upgrade guides what it should be
  • NHibernate.HibernateException : Could not instantiate cache implementation – It look like second level caching was now enabled by default and we hadn’t added configuration for it. We kept getting “Second-level cache is not enabled” messages. We disabled it and fixed this problem by explicitly turning it off. The property key is hibernate.cache.use_second_level_cache and turn it off by using the value false.

For the most part, considering how much of the core hibernate functionality had changed, we haven’t had too many issues although it’s still early days. We are noticing slightly different behaviour in the way that the flush semantics seem to be working (maybe auto flush mode is on by default now) though everything is still working quite pleasantly.

Announcing the Release of SharpZebra 0.90

Printing to the Zebra branded thermal transfer printers requires knowledge of their proprietary EPL2 language. Searching the net for a nice way of using EPL2 to communicate with these printers turns up a number of small projects, though none of them particularly ideal for integrating with a well written C# application, with most of them effectively getting you to copy and paste code into your project that you shouldn’t have to maintain.

Sharpzebra is a new open source project, written in C# that gives you access to a better printing API that abstracts away the EPL2 language concepts. I hope that it helps you spend more time putting together the things you need to print instead of working out how to print. See the Two Minute Quickstart here.

Download the binary release (dll), or binary with the project source code here.

Faster MSBuild Scripts – Convert ItemGroup to CreateItem

Speed, speed, speed… I wish MS tools would give me faster and faster feedback.

My lesson from last week – stay far away from ItemGroup elements in MSBuild files for most normal fileset equivalents (most especially if they only get used once). They are far better as CreateItem elements (though unfortunately only declarable within a Target element), taking almost the same syntax.

The result – instantaneous execution of any other targets outside of the one that uses these items, and a quicker ability to fail faster if you mistype the target name. Maybe it’s time to convert all of our targets to Nant?

« Older posts Newer posts »

© 2024 patkua@work

Theme by Anders NorenUp ↑