BottleIT - Software development

Design Patterns and Wine Tasting

by Peter Hancock 25. August 2007 08:36

These two go together surprisingly well. Apart from the fun inherent in drinking wine, these two fairly distinct areas share a common thread. Vocabulary. It’s difficult to truly taste a wine until you know some of the flavours. It’s taken a few years, but I’ve learnt what oak, truffles, cigar box, cedar, tobacco, tannins etc. mean - to me. They also tend to mean fairly similar things to other people. It’s good, because I know now what flavours I like. I can use these words to help me define a wine, and from that, communicate to others the wines that I enjoy. Design patterns are similar. A vocabulary which can be used to communicate how an area of software actually works. It’s also a way of saying what types of patterns complement each other and what don’t.

I wrote a threadpool once which used the command pattern to encapsulate the process to be threaded. That object was submitted to the singleton threadpool queue, which was protected by the double checked locking idiom. The singleton used a facade and an adapter to start up threads and execute the command before putting the threads back into a wait state. Now try explaining that to somebody who doesn’t understand the patterns involved. The beauty of patterns is that they can sum up the way a group of objects relate into only a few words. I remember when Taka code reviewed my original threadpool, he lent me The Book on patterns. I was surprised how many I had actually implemented - without even thinking about it.

The problem that I see with patterns though, is that many of the “architects” I’ve dealt with try and tell developers to “use such-and-such” a pattern. Patterns help us communicate ideas, but unlike libraries, or ActiveX controls, or whatever other pluggable compileable unit you choose to deal with, patterns just don’t cut it as plug and play building blocks. We should be highlighting that patterns help us develop by helping us communicate.

The wine maker doesn’t sit down and say, “OK, I’m going to make a wine that has strong earthy truffle notes with just a hint of oak, and some strong tannins”, and then proceed to make that. Instead, the wine maker takes the raw materials, the knowledge of the grapes, the climate history over the past however many months - adds a touch of mystique, a hint of art, and LOT of experience - and produces a wine that should be a winner. The knowledge of the flavour vocabulary, and the experience to use it, allows the wine maker to fine tune the wine, to create a structure that is beautiful on the palate, and, depending on the grapes and market, a wine that should be drunk now, or will age gracefully.

A software developer is the same. You can teach the words, and then use the words to speed up the education, but just the act of knowing patterns doesn’t make a great developer. It’s knowing how to see the patterns, identify the weaknesses, highlight the strengths, and blend the patterns together to create a fine bottle of software. The patterns, like the flavours, will emerge. And, unlike wine, we can influence these patterns by continually tuning and refactoring the software throughout its entire life.

Hmmm… maybe another glass of Pinot is in order after that.

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Software development

Use a computed or calculated column in SQL Server

by Peter Hancock 13. November 2005 00:52

We have a simple contact table CONTACT - FirstName - LastName - DateOfBirth It’s wrapped as a C# class. (with appropriate constructors and other logic to instantiate from the database)

class Contact
{
	public string FirstName;
	public string LastName;
	public DateTime DateOfBirth;
	...
}

We want to list all the contacts who are over 18. So we do something like…

   foreach(Contact currentContact in rangeOfContacts)
      if((DateDiff(DateInterval.Month, currentContact.DateOfBirth, DateTime.Now) / 12) > 18)
         Console.WriteLine("{0}", currentContact.LastName);

Basically, we’re pulling the date of birth from the database, and then using our own code to calculate the age. Of course we could wrap the age up as a property of Contact, and we could even extract the year difference calculation method into a utility class in case we need to do other whole year based methods. I’ve seen this code a lot in my time. But why not let the database do it? Create a calculated column on the table…

CREATE TABLE Contact(
	FirstName		VARCHAR(20),
	LastName		VARCHAR(20),
	DateOfBirth 	DATETIME,
	Age 		AS Cast(DateDiff("mm", DateOfBirth, GetDate())/12 AS INTEGER)
)

It’s pretty simple, and it means everyone uses the same method. Yes - it does bend normalization rules, but I think it increases readability far more. Plenty of other applications for it also….

CREATE TABLE ExpiryThingy
(	
	ExpiryDate DATETIME,
	Expired AS (CASE
	                 WHEN (ExpiryDate < getDate()) THEN '** Expired **'
	                 ELSE '** Valid **'
	            END)
)

Go to town!

Currently rated 5.0 by 5 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Software development

Agile teams and rotating developers

by Peter Hancock 12. February 2005 23:07
I've been kicking this idea around with a guy from work for about 6 months.

I'm currently working in a team that has an extremely good development environment. I was given a config spec for Clearcase, and was able to use this to immediately download the entire sourcecode base, the tools, and the utilities to build the software. All that was required was my standard development PC, and the support guys to "push out" a particular control package. It worked wonders. Download and compile with the application working first time in under 3 hours. Unfortunately, our project is missing automated build scripts, unit testing, code coverage and analysis and documentation tools.

Then - I looked at another project in the same company, with developers with skills similar to mine. The installation and development was what I would loosely call a mess. Not that they weren't using the right tools, or tools different to me, or anything like that, just that you couldn't get everything from source control, and get a "standard" development machine to run it. Instead, you had to download certain tools from the net, set up specific configuration directories, class paths, environment variables and testing configurations. This project however, has great unit testing and code coverage tools, excellent documentation via a wiki page, and automated build scripts on check-in. Meanwhile, they considered our testing environment and methods a mess.

The difference is that the skill sets of the developers are in different areas. The focus in our team has been more on packaging and consistency, whilst the focus in the other team has been more on making things more automated, and unit testing for developers. There is a massive opportunity here. Why not rotate one developer out of this team, into our team, and vice versa? In fact, we have other projects also, that could benefit from this. I'm sure that there are things that both the teams I've been involved in could learn a lot from other projects, and other projects could learn a lot from us.

This all lead to the idea of rotating developers between projects, on a regular basis. I initially thought that Paul and I might be a little insane to suggest this, but after reading Martin Fowlers take, I figured maybe I'm not barking mad after all.

The idea basically goes by implementing a queue. Each project generally has around 5 developers in it. First in, first out. At the end of each month, the developer who has been in the project the longest gets rotated into the next project. In larger projects, developers spend longer periods, supports the idea that larger projects generally have a larger code base.

Advantages

  1. Seeding of ideas as new developers come in
  2. Homogeneous use of tools and techniques as developers rotate between projects
  3. Freshness. Developers who aren't enjoying a particular project know it is a finite sentence
  4. Learning. Developers are continually learning about the business environment on a macro scale. They see the business as a whole, not as "their" project.
  5. Mentoring. New ideas and techniques bought in need to be taught to existing developers.
  6. Reduces key person risk by providing a broader range of developers familiar with the project.

Disadvantages

  1. Losing a good developer to another team
  2. Time lost in introducing a new developer
  3. Cost of moving developer
  4. Increased chance of middle managers perceiving developers as swappable resources. Thanks Steve - comment below

Of the disadvantages, I think the first one is the least relevant. The point is that in a large organisation, the project is below the entire company. It is a shortsighted view if we consider that a good developer can't provide benefit to the entire organisation by being rotated around. The corollary to this is that a "bad" developer will also be rotated out. But if an organisation has no bad developers, then does it matter if a good developer gets rotated out and another good developer gets rotated in? Another area however that DOES need to be addressed is that with the rotation out of any developer there is a corresponding loss in project specific business knowledge. For example, rotating from a share trading system into a CRM system will involve the loss of that particular developer. There are two ways I think that this can be addressed. The first is to ensure that there are enough quality business analysts that remain in the team and they contain the specific business knowledge. The second way is to ensure that adequate documentation is provided for in the code. Tools such as Doxygen and NDoc go a long way towards assisting this.

Time lost in introducing a new developer will certainly be an issue in the short term. New developers will not only need to learn a probable new environment and method of doing things, but also have to come to grips with the business understanding. The first issue will be mitigated as ideas and techniques start to become more homogeneous throughout the organisation, leaving the developer with the requirement of learning the project specific business rules. Again, the creation of adequate documentation in the code will go a long way towards mitigating this.

Finally, the last disadvantage really can't be helped. There is often a cost involved in moving a developer around. The cost of moving equipment, chairs and the plethora of books, marketing toys and junk that accumulates over a developers life in their current location, is a cost that can't be ignored. Whilst each developer might move only every 3-7 months (depending on team size), there will always be some movement. I'm not really sure how to mitigate this, given agile requirements of putting developers close to users, analysts and testers where possible. This is something that the individual organisation needs to weigh up.

I really think this is doable, and Martin Fowler suggests that Thoughtworks actively do it already. An interesting thought. There is one thing that I would like to mention though - and that is that I am NOT assuming that developers are interchangeable resources. I'm proposing we rotate them because they're NOT interchangeable. There are a LOT of benefits that can be gained from differences in development skills.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Software development

Code and comments

by Peter Hancock 11. February 2005 10:00

Going through an existing C++ code base at the moment.  I have to say that a large proportion of it is pretty good.  Yet there are very VERY few comments.  I find I'm not missing them for the most part.  But then I come across some really strange code, that WAS commented.  Unfortunately, it was some of those useful comments, you know - along the lines of

/** This method returns the name of the user logged in**/ 

Now that's great - I can see that Session::getLoggedInUser() does just that.  But WHY does it do it in the way it does?  It seems a very convoluted method of querying a database and comparing roles and generally mixing things up.  So I can see WHAT the code is doing - good, self documenting code - but I can't see WHY the author did it in this particular way.  For me - the why is always important.  I can determine from the why whether the user tried the standard library method of doing it and found problems that forced them to roll their own, or I can see that the author didn't know that there was a library function that would do it, or I can see that it has to be convoluted to achieve all the hidden side affects that this otherwise simple method may be hiding.

So now, my options are

  1. Replace the current method with a library method
  2. Try and debug the current convoluted method

Now - if the previous comment had of been /** This method returns the name of the user logged by using a custom method because of a memory leak in the library method **/ then I'd know not to go down that path.

So - when commenting code, tell me why you're doing the things you're doing.  Tell me why you made the design choices you did, why inheritance instead of aggregation?  Why are you throwing exceptions by pointer?  Otherwise, I'll either assume you knew what you were doing, and continue doing it the same way when I shouldn't, or I might assume you didn't know what you were doing, and go and correct it  - when I shouldn't.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Software development

Recent posts

Recent comments