The intersection of technology and leadership

Category: Development (Page 11 of 18)

Respect is in the currency of geeks

A work colleague pointed me out to this fascinating article called, “The unspoken truth about managing geeks” that I think anyone working in IT needs to know about.

There are some great bites of information in there that I picked up including:

  • Avoid laying blame on stereotypes and look at the system that drives out certain behaviours (such as those factors amplifying stereotypical behaviour)
  • Geeks trust people who help get the job done. Geeks find ways to work around people who don’t.
  • Unlike in almost every other area, it’s often not how you say something that matters, it’s what you say. Maybe it’s because of logic but geeks detect when things don’t quite add up.

I suggest you read everything in the article. I don’t necessarily think all of it is accurate at all of the same time but it’s well written and gives people insight into why geeks often behave as they do.

Speaking at Agile 2009

Presenting at Agile 2009I’m excited to announce that I will be running my workshop again, Climbing the Dreyfus Ladder of Agile Practices at the Agile 2009 conference in just over a week’s time. This is the same workshop that I hosted at XP2009 in Italy. In addition to this, my great colleague Alistair Jones and I will also be co-presenting an experience report, Top ten secret weapons for performance testing in an agile environment. Hope you can make it to one of these. I’m really excited to be sharing some lessons I’ve learned along the way.

I’m keeping a page from the session here.

Run automated tests as often as possible

I’ve been working with a large scale legacy system (in the Michael Feathers’ sense). Strangely enough there are a small handful of tests, unfortunately most of them falling by the way side having not been added into an Continuous Integration process. Many of them no longer look relevant, others, unable to run without a specific person’s machine (due to configuration files or special databases). Others look like a mechanism for people to simply diagnose issues with plenty of tracing statements. All of this was an inevitable system without someone running all the tests all the time.

Any serious team serious about continuous integration will think hard about their development testing strategy, considering approaches that allow you to run tests all the time. The strategy needs to consider a good way of preventing side effects from other tests (global state, global configuration, or left over state in external resources) balancing out speed with good quality feedback. Staggering build processes into smaller chunks, such as using build pipelines are a great way of achieving this.

Please don’t let leave your tests to die a sad and lonely death. It will take discipline and effort to keep them running yet the results will often pay back for themselves very quickly on any system with a reasonable lifespan.

File Associations in Notepad++

I’m a huge advocate for using Notepad++ when doing development on windows. It easily beats the default notepad.exe for being function, remains fast, and its “Find in Files” feature actually works instead of the defunct windows-search facilities.

Its menu system is a little bit different from your normal windows application, and working out how to map a specific file extension to a particular format is not exactly obvious. In this case, I wanted to tell Notepad++ to treat build files as XML files. Here’s the steps you need to go through…

Open up the Style Configurator (such a developer name!).

Menu

Pick the XML language in the left most window and under the user ext: dialogue (it sits next to the Default ext: , add build as shown in the screen capture below (click on it for a bigger picture). This will now tell Notepad++ to treat files extending with the extension build to format as XML! Viola.

Associating build files with a formatting type

Happy editing.

Nant working directory

Splitting out your build file into smaller manageable chunks is a good practice to keeping them maintainable. Incorporating existing build files into your main one can sometimes be tricky, particularly when dealing with targets that depend on paths. Where you assumed you were executing one build file in a certain directory, suddenly you need to be able to run it from the root directory as well.

To maintain backwards compatibility (able to run it from the existing directory and a higher, root directory), I make use of nant’s ability to override property values (not supported by ant). Here’s the snippet of code I used:

<include buildfile="differentDirectory\deepdown\nested.build"/>
<property name="nested.build.root" value="differentDirectory\deepdown"/>
<if test="${file::exists('nested.build')}">
  <property name="nested.build.root" value="."/>
</if>
<echo message="Running nested build from ${nested.build.root}"/>

Working in Scenarios

I’ve been busy retrofitting tests to a legacy system. We think our current best bang-for-buck are integration tests, at a service layer since there is plenty of state, lots of valueobjects and most of the interesting business behaviour cross cuts several services. We’ve been trying to build up a suite of test assitants in the form of Builder/Factories yet most unit tests don’t offer much value because the way the services interact with each other (a code smell yes, but will remain for a while given the sheer amount of it).

Instead, we’ve been wrapping service methods in a more convenient wrapper class to take the noise out of the extremely chatty APIs, wrapping away logic in something that we will call xxxServiceScenario. Just as Mark has been playing around with GetBuilderFor on his projects, we’ve hung out all of our specific service wrappers off a class called Scenario.

We then pass builders into scenarios to create the different test state that we need before calling a particular service to test its behaviour. The benefits of this approach include that it’s a bit clearer to users what we’re testing (anything associated with a Scenario is part of a GIVEN block), and we can choose to change the implementation (we’ve moved from using SQL to delegating to a service once we had more confidence in those services working properly) and our test methods are shorter without resorting to setup methods.

An example test might look like:

[Test]
public void ShouldDoSomethingInterestingGivenAParticularScenario() 
{
   User firstUser = Scenario.Users().CreateMeARealUser(new UserBuilder().Build());
   User secondUser = Scenario.Users().CreateMeARealUser(new UserBuilder().Build());
   Scenario.Settings().EstablishDefaults(firstUser);

   Event onLineEvent = EventBuilder.For(firstUser).ViewedFrom(secondUser).Build()
   new InterestingService().ReactToInterestingEvent(onLineEvent);
   
   // some assertions here.
   ...
}

Some developers seem to be liking this concept, so thought I’d share it to learn what we’ve been doing.

Reducing Resistence to Dependency Injection

In one of my previous posts, I wrote about ways that you can make life difficult when injecting dependencies. I find that systems where it is difficult to inject dependencies will be harder to change, will be harder to test, and will often be intimately coupled together in all sorts of interesting ways.

Some people (rightfully) commented that I should suggest some tips about what to do. I’d initially assumed it’d be easy to put a “Avoid if possible…” in front of each statement but I think it’d be more useful to describe some approaches to reducing the resistance. Here are a few tips:

  • Tests in place – Find a seam, add some tests before starting to make changes. Work out what’s the best way you can evaluate whether or not you’re breaking behaviour in changing something.
  • Remove static calls and state – Static functions tend to be easier to test as long as they’re not calling lots of other static methods, functions and ultimately state. Experiment to see if you can turn static items into instance methods without breaking anything. For those where the static function calls lots of other static functions, use a temporary refactor (ala Working Effectively with Legacy Code) to pass in its dependency via the method signature. It’s initially more messy but as long as you follow through on all changes and ultimately remove it (e.g. when you turn it into an object).
  • See if you can “new” instances up in the constructor without breaking anything. Most calls can be harmless but sometimes they are not. If you can move the instantiation of a class to a constructor, then the next step is to pass it in via the constructor forcing anyone currently calling the method to instantiate it. Ultimately, you probably want something else to do it, but lets you isolate the class you’re investigating right now.
  • Introduce roles instead of classes – I say roles because it’s easy to create interfaces that don’t mean anything. Try to use fine-grained roles and focus clients on using them instead.
  • Migrate away from service location to constructor based dependency injection – Service location is often useful as a migration strategy when getting a system less coupled however the service locator pattern starts to fall short when you stop injecting services, and you start injecting objects with state (causing side effects across the system based on when a “service” is called). I prefer the more explicit constructor based dependency injection so that the side-effects, if any, will be made clearer and more obvious.

Hope this list was helpful. I’m not sure if it encompasses all of the things that I’m doing, but it’s a start.

Resisting Dependency Injection

How to write code that makes dependency injection more difficult than it needs to be:

  • Use lots of static calls – There’s nothing like a global function or global state that makes it difficult for people to change something. Nested static calls are even better forcing lifecycle choices across the entire application. Who doesn’t want to connect to a database as soon as you load a small part of your application?
  • "New" up instances whenever you need it – Don’t worry about if objects need the same dependencies but earlier in the application… you can create new intances of them as well! Injecting different behaviour? No way!
  • Tie yourself to concrete implementations – Objects don’t have roles. They do stuff and we want that stuff done now. Why would someone want to change the way things are done in the future?
  • ServiceLocate Everything – A variant of the static method. We can use the Service Locator to pull in anything we may happen to need. Layers in an application. Forget it.
  • Pass newly created objects into other objects – Nesting the creation of new objects makes it even harder to unwind at a later stage. You want to inject something into that class? It’ll only need to be passed twelve layers deep!

SVN+SSH

Trying to set up command line Subversion on a windows box to access SVN+SSH wasn’t as easy as it is on *nix machines.

Trying to do something like:

svn list svn+ssh://<user>@<host>:<svnPath>

results in the following error message:

svn: Can’t create tunnel: The system cannot find the file specified.

This website had the answer (an SSH executable wasn’t in the path and needed to be). Then follow this guide to set up private/public keys.

« Older posts Newer posts »

© 2024 patkua@work

Theme by Anders NorenUp ↑