Thursday, January 17, 2013

Working with Metals & the Source Code - II

In my previous post I started sharing some interesting parallels between working with metals & the code. In particular we talked about Ductility Malleability.

In this post, let's talk about:
  • Few other very important properties called Strength, Toughness, hardness AND
  • What is the effect of Grain Size on these properties.

Of course these matter to the source code as well, as it matters to metals.
Strength is something obvious to imagine as its very important property. Its ability to withstand force without fracture or undesirable deformation. The strength can be  against Tensile or Compressive forces. It can be against Impact (Toughness) or cyclic forces (Fatigue).

Once we ship the software we have no control on how it will be used!

We can of course provide an elaborate documentation which no one will read. When did you last time bothered to open the user's guide of the digital camera you purchased? When you can't make out how to alter shutter speed, you play with various controls & try it out. It may work or it may not. If it doesn't you take help from your friend or dial the customer support. When nothing works, you open user guide.

That's natural! Point is, we cannot predict how the interfaces of the software will be used, in what context, in what sequence they will be used, whether it will get passed correct data or what. We cannot predict network speed at users end. If its a client-server application, we don't know how many users will try to connect it simultaneously. We can anticipate & design for that; while making some assumptions. If software crashes or corrupts user's data; it's very embarrassing & shameful for us, no matter whether or not ne used it as prescribed.

Yes, we are talking about Strength - Tensile, Compressive, Impact, Fatigue & all. In order to be sure we are shipping a robust software, we test it rigorously inside out labs as well as with beta users or some innovative ways like crowd sourcing. Once tested, we are very careful about changing the source code. In fact many teams discourage modifying the source code after testing before release. They call it Code Freeze & with some teams I have seen it happening months before release. I cannot understand "Code Freeze" - how code can be freezed? It must flow :-). But well, I understand the motivation.
Here we take help from "Open Closed Principle" (OCP), where we close the code modification, but open to extend it. That enables us to implement users requests & bug fixes. I'm fan of OCP, but its overuse has negative side effects. Too many extensions creates too many Grain Boundaries. Yes, Let's talk about grain boundaries now...

Most real materials are Poly-crystalline. Roughly crystal is how atoms or molecules in the metal are arranged together for form a Unit. Each individual crystal in poly-crystalline material is known as Grain. Regions where grains meet is known as grain boundaries.

Material with arrangement of large individual grain size have fewer grain boundaries. Its called as coarse-grain structure. A fine-grain structure is the one which contains smaller grains resulting in more grain boundaries.

Fig 1: Coarse & Fine grain structure. source: www.sciencedirect.com

What does the Grain Size and Grain boundaries mean to the software and the source code?


One can relate Grain to individual library or a package or a class or a function etc - let's say individual components of a system. If you design component with clear focus & crisp responsibilities i.e. Single Responsibility Principle,  it results in fine-grained structure. Fine grain structure has better mechanical properties like Strength, Toughness, Hardness compared to that of Course-grain structure.

Fig 2: source: http://www.southampton.ac.uk/~engmats/xtal/deformation/control.htm


However there is one problem with fine-grain structure.


Grain boundaries act as barriers to slip. This is because they have random crystallographic orientations, which means that the slip systems of adjacent grains are not aligned. When a dislocation reaches the grain boundary it must either change direction or stop moving. Changing the direction of dislocation movement uses up energy so the plastic deformation of the material becomes more difficult.


That's good! But Oh, that's not good as well!! We need to have our code fine-grained so that it has required strength, toughness & hardness, but at the same time we also want to be able to shape it when we want!
Well, large number of grain boundaries does not necessarily mean that code cannot be changed. As explained in above figure boundaries arranged in haphazard way prevent relative movement of grains. But if they are aligned, they can support the movement.

In deed, grain boundaries represent interaction between individual components of software. A badly designed software typically means badly arranged grains. There is always a "desired fine-grained structure" of the code and "undesirable fine-grain structure". The desired ones are Highly Cohesive & Loosely Coupled systems. They happen when one designs with "Open Closed Principle", "Single Responsibility Principle" & design-by-contract. Such a system has high strength, toughness & hardness, at the same time they are easy to change as well!

How "undesirable fine-grain systems" are formed? This typically happens when we have a big team formed rapid ramp-up, writing code without tests & version control discipline. Every developer starts writing code with nes half-cooked understanding of the system. There is no re-usability. In fact there is no usability in first place :-) as different components badly interface with each other, they are tightly coupled & no cohesion. No wonder such systems are brittle in nature. Compare this with the molten metal that is  cooled down very rapidly. The rapid cooling rate results in many centers of nucleation of grains which grow rapidly & meet fellow grains to form boundaries. If the material is thick, then the rate of cooling is also uneven all over the places leading to unpredictable properties of the metal.

But don't worry, they can be cured. You only need to put them into Refactoring furnace, heat it above critical temperature where grain structure gets corrected & then cool it down at controlled rate. But you need to fuel to fire your refactoring furnace, how you will do that? Yes, you guessed right, that's Testability. Build testability into your code, and most other things will fall in place. Watch this video: Flexible Design? Testable Design? You don't have to choose! - by Russ & Tracy. Its amazing, it works! It has worked for me! Wish you all the best!

No comments:

Post a Comment