Geeks With Blogs
Greg Young Greg.ToString()

Some random grumblings that I have come upon this week. (Yes Jimmy I am still thinking about those comments; what I really need is a GA (geeks anonymous) meeting)

Extreme Programming:  “ So always do the simplest thing that could possibly work.“

Does this really work when dealing with creational patterns in a design?

To put this into context I will give a concrete example, the placement of factories to abstract the creation of objects. Let's propose for a minute that we follow this advice, we will end up with something like the following.

Customer c = new Customer();

an alternative approach where we use a factory might look something like the following.

public class CustomerFactory {
    public static void CreateCustomer() {
          return new Customer();

Customer c = CustomerFactory.CreateCustomer();

XP would tell us that the CustomerFactory is additional overhead that we should not be carrying as it is an additional class (additional item to manage and test). The goal set could be succiently put as a minimalistic point of view dealing with code creation. We have at this point no reason for a customer factory, there is no polymorphism occurring or any code being placed within factory method.

What happens when we have 200 places directly calling the constructor on the customer and we decide to add some functionality; perhaps the customer object now needs a proxy wrapped around it in some circumstances to provide some additional functionality. We have to identify and change all of those 200 places to now call a proxy instead of the constructor directly, code refactorring tools can help greatly with this process if it is limited to a single source set. While this seems like something which is well within the realm of a “refactor” what if the code in question is a library that is used by many (possibly unknown) applications?

This brings us to an interesting side bar discussion on .NET in general. Many OO languages used to allow us to use the constructor of the object as a true method where it's could return some other object in place of itself. This is not the case in .NET nor do I see this becoming the case in the near future. This very slight difference causes the absolute need for creational patterns within .NET (and java)

The very possibility that such a simple change could ripple through an unknown amount of code should be very worrysome to us as architects. The base fundamentals of building an architecture appear at first to be mutually exclusive with the concept of extreme programming! We build often complex architectures of loosely coupled abstract contracts to isolate our code as a form of risk mitigation, then we turn around and say to build things in the simplest way possible and refactor to a level of acceptability completely removing the risk mitigation that we have strived to implement.

This taken in context forces one to analyze the XP rule a bit further. Is the rule saying that we should always do the simplest thing that solves our long term design goals? This is one possible method of solving our issue; but what happens when we apply this rule? How do we know our long term design goals for things we have not yet analyzed or even generated true requirements, would this not force us to use a waterfall based design approach?

Given that we do not wish to use a waterfall approach we have to presume that the rule means to do some undetermined amount of requirements “smelling” (yes I am reusing the term in yet another way). To look at the given object and ask questions such as “What is the likelyhood that we will need polymorphism here”. One can often identify objects that will never require polymorphism in code as they relate in a 1-1 method with a noun within a domain that is so specific that it is eXtremely :) unlikely that it will ever have multiple related definitions or functionality. One should also be focusing on the risk/reward analysis involved with the change, how many places it will affect if we later try to refactor it. Is it a change that is rather isolated or does it cross our current boundaries?

A group of developers who must always be concious of such things is those who write reusable framework type code that gets included in many projects. When you have many applications consuming a framework type library (either internal or external customers). You have to focus on the public contract of that library. A “refactor” which is incredibly simple within your library could end up bubbling out to 1000s of hours of code changes on the consumer of your library. Anyone who has been on either side of this particular fence knows very well it is a bad situation.  (It is important to note here that invariants also play a huge role in the contact changes, remoting events 1.0-1.1 ahem)

Perhaps one should look at the XP rule in a slightly different context and apply it only to internal code. That is, when dealing with code internal to your particular system that a very agile method should be followed. In the example above if the concept of a Customer is an item that is not exposes beyond the boundaries of my library, then I can easily just use a constructor as I can at any point be completely sure in the fact that I do not have an undetermined number of dependencies upon it. Because of this I can in the future estimate the time and cost associated with such a change simply by finding the number of places that are using it within the context of my library.

When we are dealing with public contracts; a different rule should be applied. Public contracts should be designed up front to support possible changes in the contract. This is a basic risk mitigation process, we have no idea what the repercussions of a contract change in the future will be, they may be eXtremely high :) Our main goals as architects should be to minimize the risk of such changes, the way that happens is by designing up front not the most simple contract but the one that isolates the rest our systems from a reasonable amount of change. I am not saying here that we should be writing the most flexible contract possible, but we should be atleast looking towards possible (even likely) changes that may occur. Yes in my mind my thought are heading back towards a book I read some time ago that I recommend anyone read if they have not read it previously which takes this thinking a bit to the extreme.

Now back to our creational patterns and making our decision. Our first question should be what are the number of places that will be using this constructor? Our goal is is to try to define the risk associated with a possible refactor to a factory method. If it is in a public contract this risk should immediately be placed at a high level. If it is internal and frequently used we should also consider it to be a high risk object. When it comes to high risk objects, error on the side of managing the risk!

What happens if we create the factory and it in the entire life cycle of the project never has behavior added to it? Well we lose about 3 minutes worth of work. Now think about what happens if we don't create and we later need it... Yeah, I'll create it.




Disclaimer: These are just some random thoughts: I do not express explicitly or implicitly any form of warantee on these thoughts nor do I assure that they make sense at all.


Posted on Saturday, January 28, 2006 3:08 PM | Back to top

Comments on this post: XP and Creational Patterns (Risk Mitigation)

# re: XP and Creational Patterns (Risk Mitigation)
Requesting Gravatar...
Amatuer opinion here:

If faced with choosing between simplest design (constructor) or good design (factory), go with implementing both. If there are external references, they can still refer to the original, whereas your factory can be used by all new implementors of your library - document that the constructor is a deprecated method so developers can gradually move their code over to the safe code. Next release of code, make the constructor internal. Just a thought.
Left by Joe Balfantz on Jan 30, 2006 4:31 PM

Your comment:
 (will show your gravatar)

Copyright © Greg Young | Powered by: