Simple Design - examples of when it works (or doesn't)

Attendees: 
William, Tom, Angela, Amanda, and the Smalltalk guy.

A few days after the open space I headed into King Tut's exhibit at the AGO. The previous time Tut had passed through town was in the 70s when I was a kid. My school had been too cheap to take us kids to see Tut, so I sure wasn't going to miss my chance this time around.

At the exhibit were quite a few examples of Shabti, wooden statuettes carved to accompany Tut in his tomb. A card in the exhibit explained the hieroglyphics inscribed on each Shabti: to answer the call to do labour in the afterlife on behalf of Pharaoh. Tut's tomb had around 400 Shabtis, one for each day of the year plus I guess some more to act as rotating scrum masters to produce the burndown charts.

As I walked from one Shabti to another, it crossed my mind this was an example of simple design, which had been the topic I'd proposed at the open space. The Pharaoh didn't have to do labour in this life, so why not just have these Shabti guys take care of that for him in the next life too? Also since these are "mere" labourers, they can be made from wood. No need to use gold, which was thought to be what the skin and bones of the gods were made of. Save that good stuff for Tut.

Getting back to the open space, a quarter way into the SD session I convened, Angela asked me if I was getting what I wanted from the session. The energy of our group discussion seemed to be on the wane. Actually I wasn't expecting anything. The topic had simply popped into my mind at Metro Hall because of a conference call the previous afternoon between our partner company and my team lead and me.

At the start of the open session, I described how during the call our partner had complained our design for the object model to be shared between us was too complicated. They didn’t like how in a domain object’s definition (interface) we referenced another object by a UUID instead of a reference directly to the object itself. E.g., having message.getSender( ) return a UUID instead of a Contact object. The UUID had no relevance in their domain other than as an identifier, and also required them to call some service with the UUID to lookup the actual Contact object it represented. Why not just give them the Contact object directly they asked?

I’d asked the team lead the same question earlier. The reference by UUID was a design he had seen work previously on another project in our company, to achieve the goal of lazy loading a deep object graph. He thought that in the event we had to re-hydrate such an object hierarchy from a serialized version on disk, having the UUID references would save us from loading objects until the user actually needed access to them. This could help us avoid blowing the memory limitation imposed on our app by Android, for example, and the extra cycles for unnecessary deserialization of objects.

Well, the partner company developers stood their ground and advocated for a simple, natural reference-by-object design. After the call, the team lead and I re-considered our requirements. Was there a need to persist and reload the object graphs? Probably down the road, but not now. Would our object graphs become so deep or wide to cause out-of-memory exceptions? Probably not, certainly not now. Most importantly, did we want to provide an object model which not only our partner but a slew of other third party developers would find natural and straightforward to use? Of course.

Consequently we replaced the UUID references in our model and sent a refactored code drop to our partner who were happy their programming life was simplified. We had to change several dozen sets of interfaces and implementations, but fortunately I had written a code generator to automate creation of the source for these, so the change was a simple matter of updating csv interface definitions. I also pointed that with AOP and customizing some open source deserialization lib we could transparently “inject” lazy loading into our implementation if the requirement arose down the road. In the meantime, keep it simple, K I S S.

The conference call with our partner and the following discussion with my team lead were still fresh in my thoughts the next morning for the open space. Just because a complicated design had worked in another project wasn’t enough justification to apply it to our project. In the space I was open to hearing from others about their experience with simple design, in particular cases where simple design turned out not to be the right choice.

The flow of our conversation, being open, didn’t follow any type of agenda. My recollection is that Tom talked about varying design requirements in a general-purpose framework versus business logic modules. Amanda reminisced about a situation where an inappropriate framework “the core” had been imposed top down on projects. The in-house framework was not appropriate because it had been designed in isolation of the real requirements of the projects it was later imposed on.

The consensus of our small group was that from our experience simple design always worked when such real requirements were kept in sight. We agreed that as requirements change, a simple design can always be evolved to accommodate, either incrementally or even transparently to its users, without the need to over-complicate the design in advance.

Unaided by structure and agenda, the energy of the session did wane midway through. The participants took advantage of the law of two feet and gradually left, one by one. The session ended with the remaining duo talking about Smalltalk.

To the other agilists who participated in this Simple Design session, I call out to you as Osiris called out to the Shabtis, please feel free to contribute your share of cognitive labour here, and add your thoughts before the sands of time envelop our memories.

AttachmentSize
shabti200.21 KB

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
Syndicate content