Documentation (photos) from Agila Sverige open space session about retrospectives

Posted by Chris on June 25, 2008

This is just a very short post linking to a couple of photos that we took to document an open space session about retrospectives and effective meetings, which we hosted at the Agila Sverige 2008 conference. Since some people asked to have them, the photos can be found at the Blueplane Flickr photostream (descriptions and photographed writing in Swedish only).

The really short summary for non-Swedish speaking is that the session started out discussing why meetings are sometimes not very effective, and moved towards defining areas to focus on to improve them. Unfortunately we did not have time to get down to how to improve in these areas, but the session concluded that the most important area to focus on (of those brought up) is to work on creating an environment that encourages involvement.

Facilitator tip: Break contact when you are the centre of attention

Posted by Chris on June 25, 2008

As a facilitator, your role is normally a neutral one with regards to whatever is discussed. Your job is to help and encourage other people to engage and discuss in an efficient collaborative way. A common problem that occurs is when a facilitator is not seen as a neutral person by some or all of the group being facilitated, and instead is seen as a leader. In the presence of a leader some people will turn into a passive mode, expecting to be told what to do instead of figuring it out for themselves.

I have experienced this in many different team meeting situations, such as retrospectives or daily standup meetings. For instance, a common failure mode of daily standups is when team members address the Scrummaster (or whatever you call your role as a coach) instead of the rest of the team when they inform about their progress. While one person is interacting with the Scrummaster the rest of the team zones out just waiting for their turn.



Photo by bombom

I use a very simple technique when this happens. I simply look away, or perhaps step behind someone else, to break direct contact with the team member addressing me. As simple as this is, I find it very effective. Even if I only look down for a second, when I look up again the person talking has usually gotten contact with someone else in the group and is now addressing the group as a whole.

Great Developers

Posted by Chris on June 17, 2008

Great developers know that writing code is a much smaller and easier task than understanding and modifying code is. Therefore, they make sure that the code they write is easy to understand, and possible to extend by writing new code rather than rewriting old code.

Furthermore, when a great developer encounters code that is difficult to understand or that makes it difficult to add the new functionality they are working on they do not work around it, or add to the mess by adding more code to an existing big ball of mud. Instead, they follow the mantra of first simplifying the existing code to make it easier to understand, then improving it to make it easier to change, and finally they make the changes necessary to add the new functionality.

Finally, a great developer never leave code in worse shape than what they found it in, but they do not always strive for perfection. They achieve a balance between improving existing code and adding new functionality (in Swedish we call this “lagom”).

This was the message of a presentation entitled Great Developers, Principles and Patterns for writing good code, that I gave at the Swenug Code Camp in Gothenburg last week (pictures available on the Blueplane Flickr photostream, link to slides and code at the bottom of this post).

The presentation had two major parts, each accompanied by a demo with code. In the first part I talked about how developers differ in how much they care about the code they work with, using the story of stonecutters and cathedral builders. I often hear people complaining about how their team members do not care about code the way they do. They then go on to talk about how they have tried teaching them design patterns, Open-Closed Principle, low coupling and separation of concerns etc. I think that although this is important knowledge, the first step towards becoming a cathedral builder is not to learn about such things but to understand and get into the mindset. To do this we need to teach simple work patterns, how a cathedral builder thinks when he encounters code that is not easy to work with. If we can influence someone to think about improving code using something as simple as extracting short code fragments into named methods they will be well on their way towards thinking like a cathedral builder.

In my first demo I played the role of a developer with the task of adding some new functionality to a system that already has some very similar functionality implemented. The existing code was implemented in the PictureListController class, shown below:

	public class PictureListController
	{
		private PictureListView view;

		public PictureListController(PictureListView view)
		{
			this.view = view;
		}

		public void ShowTopPictures(int age)
		{
			// Is visitor allowed to see pictures?
			if (age < LoadsaPicsConfig.MinimumAge)
			{
				Logger logger = Logger.Instance;
				logger.Log("Under age violation!");
				throw new NotOldEnoughException();
			}

			PictureRepository repository = new PictureRepository();
			List allPictures = repository.GetAllPictures();
			allPictures.Sort(
			    delegate(Picture first, Picture second)
			    {
				    return second.Views.CompareTo(first.Views);
				});

			view.SetPicturesToShow(allPictures);
		}

		public void ShowPicturesByRank(int age)
		{
			if (LoadsaPicsConfig.MinimumAge - age > 0)
			{
				Logger.Instance.Log("Under age violation!");
				throw new NotOldEnoughException();
			}

			PictureRepository repository = new PictureRepository();
			List allPictures = repository.GetAllPictures();
			allPictures.Sort(
			    delegate(Picture first, Picture second)
			    {
				    return second.AverageVote.CompareTo(first.AverageVote);
				});

			view.SetPicturesToShow(allPictures);
		}
	}

My task was to implement a new way of listing pictures, this time ordered by most downloads. Instead of simply creating a new public method ShowPicturesByDownloads and copy-pasting code from the other methods, I instead decided to improve the existing code to make it easier to add the new functionality. I first simplified the two methods a bit and found out that they really did the same thing in the first part, so I could extract that into a common method. I noted that I should probably move that method somewhere else sometime, but right now I was OK with leaving it there (lagom). With that code extracted, I noted that the two methods was exactly the same except for the delegate used to sort the pictures. Since the client code that calls this code was also part of the same system I had the option to change the public methods of PictureListController and update any callers accordingly. The final result is shown below:

	public class PictureListController
		{
			private PictureListView view;
			private IComparer sortAlgorithm;

			public PictureListController(PictureListView view,
			            IComparer sortAlgorithm)
			{
				this.view = view;
				this.sortAlgorithm = sortAlgorithm;
			}

			public void ShowPicturesSorted(int ageOfVisitor)
			{
				VerifyOldEnough(ageOfVisitor);
				List allPictures = GetPictures();
				SortPictures(allPictures);

				view.SetPicturesToShow(allPictures);
			}

			private static void VerifyOldEnough(int age)
			{
				if (age < LoadsaPicsConfig.MinimumAge)
				{
					Logger logger = Logger.Instance;
					logger.Log("Under age violation!");
					throw new NotOldEnoughException();
				}
			}

			private static List GetPictures()
			{
				PictureRepository repository = new PictureRepository();
				return repository.GetAllPictures();
			}

			private void SortPictures(List pictures)
			{
				pictures.Sort(sortAlgorithm);
			}
		}

Now I can extend the functionality with infinite sorting orders, simply by instantiating the controller with different IComparers. This led me in to the second part of my talk, where I discussed principles such as Single Responsibility Principle (SRP) and Open-Closed Principle (OCP). I ended with a demo where I showed how a piece of code could be refactored from an implementation that did not follow SRP or OCP, into one that was very open for extension and had clearly separated responsibilities.

My slides and all of the demo code is available on Blueplane’s web site (or download zip file directly).