2011-11-16

Modeling The Real World vs. Designing Software

Technikmuseum_Speyer_12I started writing a response to comments on a previous blog post, and it turned out long enough to become its own post. The question was on whether you should relationships in the "real world" to decide on relationships in your object-oriented designs.

"Is-a" and "part-of" are concepts from object oriented analysis, where you try to model "the real world" in terms of classes and objects. That is, by looking at the problem you are trying to solve, you could come to the conclusion that a customer "is-a" person, and that a street name is "part-of" an address.

In the early days of object orientation, it was assumed that you could simply transfer the relationships you found in that analysis directly into your design for good results.

There are (at least) three reasons why this doesn't generally work well, in my experience:

  • when we analyze the "real world", we typically model the problem space. When we design software, we model the solution space. Although there are often similarities between the two, there is no direct mapping - in fact, finding a good model for the solution is the most creative (and important) act in developing software. Assuming that an "is-a" relationship in the problem space will directly translate into inheritance in our solution space needlessly restricts our creativity, and thereby leads to inferior solutions.

  • for me, the primary goal of software design is to manage dependencies in the design, so that the resulting system is maintainable and extensible (because successful software is software that will need to be changed). As a consequence, there are forces working on our designs that don't exist in the "real world", and therefore considering just "real world" relationships won't help managing those forces. Just take the famous "a circle is an ellipse" example: while true in mathematics, depending on what you need a system to do, reflecting this relationship in your design can violate Liskov's Substitution Principle, and thereby lead to brittleness and unnecessary complexity. That is, a relationship that is absolutely natural in the problem space leads to problems when transferred as-is into the solution space. Another example: both a customer and an administrator are persons, but that commonality could be totally irrelevant to the solution of your problem, and then modeling it in your design would be a waste, at best.

  • in the English language, there is no unambiguous rule about when to use which phrase, anyway. Yes, you could say a customer "is-a" person. You could as well say that personal information is "part-of" a customer. Or that a person "has-a" role of being a customer. It can even make sense to say that "a person is a customer". So you really can't use natural language semantics to decide which relationship to use in your code.

So, using those relationship names doesn't really take the burden off your shoulder to choose wisely which relationship makes the most sense in your specific case. And an experienced designer will - whether explicitly or by gut feel - choose the relationship that leads to the most SOLID design. and he knows how to refactor to a different relationship when his understanding of the forces in the code changes.

2011-08-01

An Agenda for Backlog Grooming

London Zoo - The Hairdresser
When training and coaching teams to use Scrum, I'm starting to put more emphasis on Backlog Grooming - having the whole team maintain the Product Backlog during the Sprint, so that it remains in good shape, the team keeps a grip on the vision for the project, and there are no unpleasant surprises when it comes to Sprint Planning.

Inspired by "Collaboration Explained" and Roman Pichler's blog post, I created a general purpose agenda for backlog grooming, that so far has worked quite well:

  • Opening - help people arrive physically and mentally, review the agenda, do a quick round robin check in, review actions from last grooming.
  • New Learnings - what have we learned that we want to capture in the Product Backlog? Ideas for new stories, obsolete stories, significant changes to content, estimates or priorities?
  • Prepare for Next Sprint - identify the stories that should go into the next Sprint Planning and make sure they will be prepared according to the Definition of Ready.
  • Identify Stakeholders and Dependencies for Next Sprint - focus on the question: looking at the stories selected for the next Sprint Planning, who needs to be invited to that planning meeting?
  • Risks for Upcoming Sprints - looking further ahead, what are the upcoming risks? Which of them should be addressed now, and how - for example by splitting stories, by scheduling investigations, spikes etc.?
  • Closing - any open ends that need to be addressed? Review Action Plan. Mini-Retrospective, e.g. Plus/Delta.
What are your thoughts on this agenda? What do you do in Backlog Grooming? How would you change this agenda for your team(s)?

2010-08-23

The Shu Ha Ri of Inheritance versus Composition

Tauziehen
For ages now, there is an ongoing discussion (to not say war) in the OO communities on wether it makes sense to prefer Composition over Inheritance or not.

My personal impression is that a lot of the heated debate stems from confusing advice given to beginners with what the experts do. A useful mental tool I like to use in occasions like this is the concept of Shu Ha Ri. Here is how I currently think about it:

Shu

You are (relatively) new to object oriented design. Inheritance is rather easy to understand, polymorphism a little bit more abstract. Inheritance is easy to do, composition a lot more work, or so it seems. It's likely that you are overusing inheritance, and that you could benefit from making more use of composition. That's fine, it's the usual learning step you have to take. Once you experienced how inheritance works (and where the problems lie), it's good advice to favor composition over inheritance, so that you can learn what the pros and cons of that approach are.

Ha

You have experienced the perils of overusing inheritance. You have experienced the flexibility that composition brings you - and where investing into composition actually doesn't seem to pay back much. It's time to start experimenting with a balance of inheritance and composition, and to find your own rules of when to use which.

Ri

Thinking in terms of inheritance versus composition doesn't make much sense to you. You know that both are just tools in your quest of producing maintainable, SOLID code. And you can easily refactor code from using inheritance to composition and back on a whim, so why make a fuss about it? Just use whatever your gut tells you makes sense at the moment.