patkua@work

The intersection of technology and leadership

Page 33 of 53

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.

XP2009 Day 3

The keynote
Bjarte Bogsnes gave, in my opinion, the best keynote out of the three speakers, where he discussed his experiences applying the concepts discussed in Beyond Budgeting in Statoil. He talks about why do you want a system that is based on assuming you cannot trust everyone? Instead you want a system where the default position is that you trust everyone, and that you manage those that you can’t by exception (and not the other way around).

He talked about how the trigger for Statoil was two fold – internal and external. External pressures included the fluctuating nature of the sale price for barrels of oil, and internally it was the social pressures of actually having systems that encouraged all the good things that they said they did, yet didn’t neccessarily encourage, where policies were largely authority based (sign off) compared to those of trust and respect.

The key question they asked was, “How do we create the conditions that let people make good decisions and execute them well?” Compare this to, “How do we make people make good decisions and execute them well?”.

Interesting their solution laid in removing the “traditional” budgeting scheme, asking people to “do the right thing”. Resources were available but not yet preallocated. I remembered most his metaphor, describing most businesses operating like a bank that is open for four weeks out of the week. Customers need to predict exactly what their year is going to be like, and ask exactly for the right amount.

They identified that budgets typically have three overloaded (and often opposing goals), representing performance targets, forecasts and resource allocation. They implemented a system splitting each of these different aspects into different systems to achieve better visibilty and improve the quality of conversations around each of these topics. They created a system to ensure there was alignment at all different levels, directly creating KPIs out of the strategy, generating actions out of the KPIs and then individual goals out of the actions.

Industrial Logic’s eLearning Tool
I had a great chat with Joshua Kerievsky, founder of Industrial Logic and he asked if I wanted to see their “eLearning” tool. I’m glad I did as well because I think it’s an amazing environment for all developers who want to be professional. I don’t think calling it an “eLearning” tool does it justice. In a nutshell:

Imagine gathering some of the world’s best experts in different programming disciplines such as refactoring, automated testing, design patterns and imagine working with them on the same team. You get to watch over their shoulder as they explain what they’re thinking as they execute, you get to practise an exercise with them and receive immediate feedback, and you get to interact with the most engaging pieces of training I’ve ever seen (including many of the hands on training classes). All of this just happens to be online.

They’ve put a tremendous amount of effort responding to student’s feedback and its narrow focus on (currently) developer related material means they can give some surprisingly detailed feedback including comparisions and alternatives as a result. The tool itself only happens to help deliver the message and, more importantly, he’s managed to capture so much knowledge in the “albums” they’ve already put together.

Go check it out. Take the tour and then have a look at some of the albums.

Telling Your Stories: Why Stories Are Important for Your Team
Fellow retrospective facilitators Diana Larsen and Johanna Hunt ran a fun session that was particularly engaging considering, managing to have the busiest session on the last slot of the last day. The title of the workshop didn’t describe the session as accurately as it panned out as it was extremely creative workshop where we looked a number of a card games often used for story telling in other areas, and then brainstormed ways in which we could create cards and a process to help use stories in an agile environment. The group had some fantastic ideas and even heard a few people walk away saying, “I need to get some of those cards made!” to take back to their teams.

Conclusion
I’m pleased that this year’s conference seemed to have returned to what roots it was for me four years ago. I appreciate the fact that there are still so many people passionate about “doing the right thing”, about helping each other out, and that the main motivator is still to “grow, learn and get better” first, instead of “making money” prioritised as number one. Thanks to all the wonderful people I met at this conference (for the first time and again), and the great memories I took away.

XP2009 Day 2

Thoughts about the second day
Ivar Jacobson gave an equally uninspiring keynote, talking about “What they don’t teach you about software at school: Be Smart!” In it, he focuses on the fact that it’s not only enough to try to “Be Agile”, but you need to “Be Smart”. Unfortunately many of the items that he talked about didn’t really seem to be any different from “Being Agile” and that he had obviously targeted the wrong audience.

I’m glad the conference ran with an open space session, this year introduced by Willem Van Den Ende and Lasse Koskela. I suggested a topic titled, “The Kanban, Lean, Agile Divide” and I felt we had the best quality discussions during this open space. I wanted to answer a number of questions including:

  • Did people know about the Kanban Community?
  • How active were people in that community?
  • Did people perceive a divide?
  • And if so, why?

Out of around the 12 people participating, probably only two or three hadn’t heard about the community, and only one or two people were active in participating (in the mailing list portions). We had lots of discussion as to what people considered as Kanban as well.

kanban

First page of notes from the open space session

We noted down the mailing list, available on Yahoo Groups: Kanban-Dev and several “published” resources including the paper, Kanban Vs Scrum, and the book, Scrumban.

When asked about what Kanban was the participants, here’s what we recorded:

  • Elements of one piece flow (particularly limits to WIP or Work In Progress). Translated into practical terms, it meant focusing on one story at a time (as a team or as a pair)
  • Kanban was an alternative scheduling technique
  • Unprescriptive, or less prescriptive (relying on other practices to help out)
  • Constantly evolving
  • “Good for maintenance”
  • Most people considered Kanban a “Practice more than a methodology”, though there was general agreement that some people are trying to turn it into more than that
  • Focused on delivering “Minimal Marketable Features”
  • Quote from Tom Poppendieck, “Scheduling and Workflow are orthogonal”. We expanded upon this for a bit and a more concrete example is you can use different scheduling techniques such as Kanban or Timeboxes with the same workflow such as a simple, “To Do, In Progress, Done” workflow.

I recorded that some people were still doing sprint/iteration planning whilst using Kanban though I don’t remember if we got into the details.

I also recorded two concerns, such as knowing, “When do we get stuff done?” and a very “Loose Terminology” leading to lots of confusion, particularly the overloaded associate with Kanban (as a practice) and Kanban (as a methodology).

When asking the question, “Is there a kanban divide?” some answers included, there is maybe a divide in a community sense, and when probing further, when interpreting Kanban as a practice, not a methodology there wasn’t however there was definitely a sense when treating Kanban as a methodology and not as the practice with a feeling that some people in the community wanted to make money.

kanban2

Last page of notes from the open space session

We asked why the community divide and understandably, there was no real community around to openly discuss Kanban (as a practice) and felt similar to those that had been around during the XP early days. There didn’t seem to be any general list for “agile practices” with extremeprogramming and scrum-dev mailing lists. It’s also not the first time practices have had their own list, like the pairprogramming or the test-driven-development lists. We did note down that there were several potential ones the community could have joined including lean-agile, lean-dev instead of creating their own kanban-dev.

In the afternoon, I went along to the panel on Lean Software Development although I seemed to come away with the same questions and less answers. One of my questions about budgeting was answered by the next morning’s keynote, while another focusing around the lack of discussion around practices seemed to be dismissed by Mary Poppendieck as, “I don’t believe in practices”, maybe best surmised as, “I don’t know” (which I would have also been happy to take).

The evening was an impromptu beach BBQ held by the awesome folks at Agical. Whilst a small company, I’m glad to see them still as passionate and having grown year upon year with more enthusiasm about a huge variety of topics. The BBQ was amazing and I know that everyone had a great time.

More to come…

XP2009 Day 1

General impressions about the conference
I really enjoyed this year’s conference with the combination of a remote island in Italy and the small numbers (100+) giving many great opportunities for chatting with our experienced practitioners, and a handful of academics about lots of different topics. I found it refreshing that there seemed to be significantly more experienced practitioners and thus, I found it extremely nice to be able to chat about similar experiences rather than simply unidirectional advice I find when present with a higher proportion of beginners.

conferencepool

Who wouldn’t want to gather around this place for some great conversations?

The quality of sesions was better than the last two conferences, once again focused less on the introductory nature and more focused on specific aspects. Of course, I had recommendations about how to improve, particularly the organisational aspects, of the conference and I’ve at least had an opportunity to give that feedback having shared a return train with one of the organisers for next year’s conference.

Thoughts about the first day
The first part of this day was a keynote delivered by lean evangelist, Mary Poppendieck. Titled, “The Cultural Assumptions behind Agile Software Development”, Mary proposed that there are several (American-style) cultural assumptions behind many of the agile practices that make it all the more difficult to implement. She referenced heavily the work discussed by Geert Hofsted in his book, Cultural Dimensions.

I didn’t find the keynote particularly inspiring, nor particularly challenging. Country-based cultural dimensions are just one of the factors that permeate the way that people behave. As an agile consultant, you end up fighting corporate culture, and the systems that encourage and maintain that corporate culture and I see country-based cultural dimensions yet another contributing systemic effect. This does not mean that just because a country has a high degree of individualism, working in pairs or working collaboratively in a team will be impossible (perhaps just all the more difficult). As much as I enjoy hearing Mary speak, I also found her presentation a little bit too heavy in the whole powerpoint presentation with far too much text and outdated clipart.

I also ran my workshop in the morning, titled “Climbing the Dreyfus Ladder of Agile Practices” and want to thank all the experienced people that attended as it resulted in some really rich discussions. We managed to discuss seven different agile practices in detail, brainstormed a large set of behaviours for each, classifying them and classifying them into the different levels described the the Dreyfus Model of Skills Acquisition. The results from the workshop can be found here (photos to be updated).

In the afternoon, I helped out Emily Bache’s coding dojo, focused on Test Driven Development. We saw four different pairs tackling four different coding problems using different tools and languages. I learned about the tool JDave (it’s still a little bit too verbose for my liking), and saw different styles in the way that people executed the code kata. For me, I was hoping to demonstrate more on the pair programming side of test driven development as a pair, and I had a lot of fun even though I felt a little bit out of my depth with the tools. Thanks to Danilo for complementing my lack of experience with tools like Cucumber. 🙂

More to come…

« Older posts Newer posts »

© 2024 patkua@work

Theme by Anders NorenUp ↑