Colorless green ideas sleep furiously.
- Noam Chomsky, Syntactic Structures
"Let us concentrate on explaining to human beings what we want a computer to do"
Wednesday, 12 June 2013
Saturday, 25 May 2013
Goldilocks services
Github is a document store. Each repository is a document. Transactions are easy to execute within a
document and only eventually consistent across documents.
If your documents are too large, the scope of your transactions will be excessive, and you will get contention. If your documents are too small, the scope of your transactions will be insufficient, and you will be forced to manage changes across multiple transactions.
Each service is an aggregate root, so design them so that they can be evolved independently.
Saturday, 18 May 2013
Second order poka-yoke
Poka-yoke is the practice of "mistake-proofing" - designing interfaces in ways that prevent users from making mistakes.
Continuous integration is a form of poka-yoke for software development. Developers are prevented from releasing (obviously) broken software to production by a battery of tests.
However, poka-yoke is about designing to mitigate specific user mistakes (at least as I understand Shingo's definition). In other words, it's about putting up safety barriers between users and anticipated failure modes.
How much better to develop in a software ecosystem that discourages not only the occurrence of mistakes, but encourages the growth of designs that do not admit the possibility of these mistakes.
My colleague Gurpreet Luthra cites the example of making heat-resistant bolts a different size to ordinary ones so that they cannot be accidentally interchanged. However, were the design to be simplified so that the engine was a single piece of metal, bolts would not be required at all.
Sometimes simplification is possible. Other times essential elements of the domain force us to introduce scope for error. Perhaps engines could be constructed differently to simplify assembly. Perhaps not. The only way to tell the difference is to be constantly vigilant for the possibility of eliminating accidental complexity.
Having thorough test coverage is good. Preventing the complexity that disrupts developers' ability to comprehend the system well enough to avoid mistakes is better.
Simple designs can not only make mistakes avoidable, they can make them literally inconceivable. By that construction, you could consider a disciplined pursuit of simplicity second-order poka-yoke.
Continuous integration is a form of poka-yoke for software development. Developers are prevented from releasing (obviously) broken software to production by a battery of tests.
However, poka-yoke is about designing to mitigate specific user mistakes (at least as I understand Shingo's definition). In other words, it's about putting up safety barriers between users and anticipated failure modes.
How much better to develop in a software ecosystem that discourages not only the occurrence of mistakes, but encourages the growth of designs that do not admit the possibility of these mistakes.
My colleague Gurpreet Luthra cites the example of making heat-resistant bolts a different size to ordinary ones so that they cannot be accidentally interchanged. However, were the design to be simplified so that the engine was a single piece of metal, bolts would not be required at all.
Sometimes simplification is possible. Other times essential elements of the domain force us to introduce scope for error. Perhaps engines could be constructed differently to simplify assembly. Perhaps not. The only way to tell the difference is to be constantly vigilant for the possibility of eliminating accidental complexity.
Having thorough test coverage is good. Preventing the complexity that disrupts developers' ability to comprehend the system well enough to avoid mistakes is better.
Simple designs can not only make mistakes avoidable, they can make them literally inconceivable. By that construction, you could consider a disciplined pursuit of simplicity second-order poka-yoke.
Saturday, 11 May 2013
Fixation and variability
While explaining Why Everyone (Eventually) Hates (or Leaves) Maven, Neal Ford divides extensible software into two categories: composable and contextual.
Contextual software is best exemplified by plugin architectures - new features are added by slotting code into explicitly provided extension points. Composable software is best exemplified by the Unix ecosystem - new features are added by wiring together a combination of existing and custom components.
So what is it about contextual systems that provokes such hatred?
The key problem when making software extensible is where to put the variability. I have a fixed set of core features, but I also want others to contribute extra features that vary depending on their needs. How do I bind the fixed and variable functionality together so that they form a coherent system?
Maven accommodates variability like a classic contextual system. The promise (and the curse) of Maven is the consistency of its build lifecycle. There is a place for everything, and everything must be in its place. Maven affords very little flexibility on the relationship between variable additions and its fixed feature set.
Rake, on the other hand, empowers developers by allowing extension via a general purpose programming language. Rake qualifies as a composable system because any means of adding new functionality that can be expressed in Ruby can be used to extend it.
In composable systems, orchestration is variable. In contextual systems, orchestration is fixed. Keeping the means of combination in userland is an additional burden on those who would extend your system, but it's more than offset by the flexibility and power they enjoy in the long term.
Your software will grow, but your relationship with Maven won't.If When that happens, it's time to leave.
Contextual software is best exemplified by plugin architectures - new features are added by slotting code into explicitly provided extension points. Composable software is best exemplified by the Unix ecosystem - new features are added by wiring together a combination of existing and custom components.
So what is it about contextual systems that provokes such hatred?
The key problem when making software extensible is where to put the variability. I have a fixed set of core features, but I also want others to contribute extra features that vary depending on their needs. How do I bind the fixed and variable functionality together so that they form a coherent system?
Maven accommodates variability like a classic contextual system. The promise (and the curse) of Maven is the consistency of its build lifecycle. There is a place for everything, and everything must be in its place. Maven affords very little flexibility on the relationship between variable additions and its fixed feature set.
Rake, on the other hand, empowers developers by allowing extension via a general purpose programming language. Rake qualifies as a composable system because any means of adding new functionality that can be expressed in Ruby can be used to extend it.
In composable systems, orchestration is variable. In contextual systems, orchestration is fixed. Keeping the means of combination in userland is an additional burden on those who would extend your system, but it's more than offset by the flexibility and power they enjoy in the long term.
Your software will grow, but your relationship with Maven won't.
Sunday, 16 December 2012
Dickens on Ruby on Rails
There is much good in it; there are many good and true people in it; it has its appointed place. But the evil of it is that it is a world wrapped up in too much jeweller's cotton and fine wool, and cannot hear the rushing of the larger worlds, and cannot see them as they circle round the sun. It is a deadened world, and its growth is sometimes unhealthy for want of air.
- Charles Dickens, Bleak House
Friday, 17 August 2012
It's all production
Every now and then, I come across a discussion about whether test code deserves as much care as production code. I understand what is meant (the answer is yes), but I don't accept the premise of the question.
All code is production code. Deployment scripts, tests, database migrations and Java controllers all play a part in delivering value to the users. If a piece of code really has no effect on production, why was it ever written?
All code is production code. Deployment scripts, tests, database migrations and Java controllers all play a part in delivering value to the users. If a piece of code really has no effect on production, why was it ever written?
Wednesday, 20 June 2012
Einstein on Clojure
It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience.
- Albert Einstein, The Herbert Spencer Lecture, delivered at Oxford (10 June 1933)
Subscribe to:
Posts (Atom)