Why are there no more two-strokes?

Traditional two-stroke engines offered a variety of advantages over their four-stroke rivals.  Their power output far exceeds similar capacity four-strokes. This is in part due to the fact they produce power twice as often as a four-stroke and partly because there are less moving parts to create drag and losses in power.  This “fewer moving parts” factor was seen as another significant benefit of two-stroke technology.  Fewer moving parts equates to fewer things to go wrong.

The late 80’s and 90’s could have been considered as the high point of two-stroke motorcycles.  The premier racing category (now known as MotoGP) featured three classes of bikes featuring two-stroke engines.  A few manufacturers had small light-weight high-powered two-stroke road bikes in their line-ups.  Of course, every silver-lining has a dark cloud somewhere. With two-strokes, this cloud has a blue tinge and a distinct smell about it.  Two strokes were notorious as being bad polluters and suffering poor fuel economy.  “Highly tuned” two strokes were also known for their light-switch power delivery.  “All-or-nothing” power delivery can be intoxicating, but it can also be annoying and down-right dangerous on public roads.  When not running at optimum engine speeds, these two-strokes expel a large amount of unburnt hydrocarbons into the atmosphere.  So much so, that even before Al Gore brought climate change to mainstream attention, most people could see that this was “altogether a bad thing”.

Of course, two-stroke technology still exists in all sorts of industries today.  Outboard marine engines often feature this technology.  But, before you start criticising your boat owning neighbour for his “careless attitude toward the environment”, know that modern outboard two-stroke engines pass the emissions tests required of it.  Direct Injection technology ensures that fuel is not wasted and pushed out the exhaust unburnt as did two-strokes of old.  The fuel is only delivered to the combustion chamber when it cannot escape out the exhaust port.  (My apologies to any reader who doesn’t understand the basics of two stroke combustion engines – hopefully I’ll cover that in an introductory manner at another point in time)

From what I have read, direct injection two-stroke engine design:

  • Eliminates the “peaky” power delivery.
  • Reduces emissions to comparable levels of a four-stroke engine.
  • Retains its power to weight ratio advantage over four-stroke engine design.

I hear you saying: “Surely they have lost some of the advantages they used to have?  Isn’t there always a compromise?”.  Well, as stated earlier, two-strokes of old were mechanically very simple.  Few moving parts with very little to go wrong.  Direct injection necessitates that things get a bit more complicated, with fuel pumps, fuel injectors and so on.

I suspect the biggest factor in why we don’t see modern “clean running” two-stroke motorcycles is largely due to the sins of their past.  Any new bike would need to overcome the old stereotypes of being polluting and thirsty motorcycles.  Given that technology exists to overcome these issues, it really is a shame the manufacturers have not risen to the challenge of marketing them in a better light.  There still seems to be a lot of sentimental folks in the motorcycling press who would like to see them return, so maybe they will, one day…

Retrofitting test cases

The main project I work on, has an automated unit test application which is built and run as part of the build process.  For our office, the team was an early adopter of the concept, but unfortunately this does not translate into extensive and well maintained set of unit tests.  Put politely: it would be good to improve this coverage.  This then raises a fairly obvious question: Where do you begin?
First of all, it is worth analysing the statement: “It would be good to improve this coverage”.  There are a couple of benefits to having unit tests and these benefits help explain the statement.
Avoidance of regression bugs.  This is reasonably self-evident.  If you have sufficient coverage of your classes, you cannot introduce faulty logic without a unit-test failing. Over the years many quality assurance staff have told me “the earlier you catch a bug, the less expensive it is to fix”. So many, in fact, that I now believe them.  (In truth I don’t think I ever doubted the “earlier = cheaper” argument) Anyway, if you are running unit tests as part of the build process and building regularly it stands to reason that any bugs introduced and caught, will be fixed cheaply.
Code re-use.  A less obvious benefit is that the code you are testing now has two uses.  One in the application and one in the test-case.  While this may seem a contrived second use, it should help with code abstraction.  The theory goes that the more usages a class has, the less chance it has of being tightly coupled with other classes.  Tightly coupled classes increase code complexity.  The more tightly coupled they are, the more likely a change in one class will introduce a regression bug in another class.
Now that we have defined a couple of benefits that we hope to achieve through the use of unit tests, it helps define where we should begin.  We want the unit tests to reduce instances of regression bugs and improve code abstraction – which is enforced by re-use.  History logs of the revision control system can be studied to show the frequency of changes in a unit.  If a mature project has a hot-spot of continual changes to a given class, then that may well be an indicator of frequent regressions and “hopeful” changes rather than “thoughtful” changes.

There is a very good chance that such a class violates rules of the single responsibility principal and in turn makes writing unit tests for it an unviable proposition.  Now that we have identified what is wrong, we have a good place to start:

  • Look through the class and identify the different responsibilities the class has.
  • Extract the responsibility that is least entangled throughout the class.
  • Write unit tests for this new class.
  • Rinse, repeat.

Once you have extracted a new class and written the unit tests, your changes for it are not necessarily complete.  As you extract more classes, there is a chance that your new class can be further decoupled from the original.  In my experience, the important thing to remember is that just because you remove a responsibility from a class does not immediately decouple the two classes.  Proper decoupling can take several iterations.As I stated, start with the easy abstractions first.  As classes become less entangled, the harder areas will become easier to deal with.  At least, that’s the theory!