Wednesday, 30 March 2016

Pulling the Plug on Date Time Parsing

Date/time logic is hard. Throw in time zones along with daylight saving and it's even harder. Recently a suite of tests that had happily been running for months started failing. There were no code changes and all the tests were somehow related to date/time ranges.

Despite this the production code was functioning as expected. It turns out the API was explicitly setting the locale to use en-GB. However the suite of tests were not.

The fix was simple. Prior to the test fixtures executing, explicitly set the locale. In order to test this assumption and see the tests pass, a temporary change on the development machine was required.

The locale was set on the development machine to another region. In this case setting to en-US was enough to cause the tests to fail. After the code change the tests passed. Any locale can be used as long as the date format differs.

This idea is pretty easy, and is very close to my technique of pulling the plug on automated tests. The test suite can now be run on any machine, even those incorrectly configured and we can be sure the tests will still pass.

Going forward for any date/time tests I will make an active decision to temporarily change my regional settings. With more codebases utilizing the cloud, relying on implicit configuration should be avoided where possible. In fact I would bet a large sum of money that many codebases out there would fail this temporary locale change. Give it a go - pull the plug.

Tuesday, 22 March 2016

Best of Breed

Spikes are one of the best ways to aid the design of software. In some cases spike solutions can open more questions than they solve. The use of a technique known as Best of Breed can assist when this arises.

Rather than producing a single spike, produce several. Either individually or with other developers working on a spike each. Each solution can then be compared and contrasted. The best parts of each solution can then be combined. Best of Breed is named for its likeness to genetics where the best genes win out for future generations as part of the process of evolution.

Example

Spike solution A has an excellent way to handle future requirements due to the open and closed approach taken. Solution B solves the data access problem in an elegant manner. Both solutions have good components. Simply combine the solutions into a single approach. This results in code that contains extensibility and good data access patterns.

Benefits

  • Neither standalone solution would have been as good as this hybrid or best of breed.
  • Multiple developers have intimate knowledge of the code thanks to collective code ownership.
  • Allows experimentation - go wild with multiple solutions trying out techniques or ideas you would not normally experiment with. Safe in the knowledge there is more than one solution to any problem.
  • Provides a learning platform. It's always good to see how and why others solve problems.

Best of Breed provides benefits above and beyond traditional spike solutions. With more than one developer the addition of multiple spikes can be developed in parallel. For individuals the construction of further solutions should be evaluated on a case by case basis. Single developers may prefer to evolve a single spike during various phases.


The term Best of Breed was introduced to myself by Paul Shannon.

Tuesday, 15 March 2016

Singleton's and the Singleton Lifestyle

The death of testability and the lack of isolation make the singleton pattern a relic of times gone by. Rarely have I had a real need to code a singleton since my first year of university. Most decisions to use a singleton boil down to scoping issues.

Singleton

Assume a game requires a single instance of a rendering component. In this example configuring and initialising the renderer may be expensive. We only want to do this once.

While this singleton renderer solves the problem of instantiating more than once it suffers from the fact there is only ever one instance. If we want multiple renderers such as a console debugger we are out of luck. Testability is also lost. If we wish to exercise the Game, we need to provide and use a real rendering component.

Static Classes

Or class instances give you the same advantages and disadvantages of singletons. You only have one instance and you can access it easily. One big difference is that unlike singletons you cannot provide static instances as arguments. In practice this is rarely a problem given you have easy access to the instance anyway. You should treat static classes as suspiciously as singletons. However static classes are not bad. They do have uses.

The renderer is now a static class. The same disadvantage as the singleton remains. We are always stuck with a single instance.

Singleton Lifestyle

When using DI you need to consider lifestyle. Singleton lifestyle is one of the most useful. Do not be confused with the Singleton pattern. Despite the name, singleton lifestyle is purely a scoping issue.

By adjusting the scoping of the renderer, the game can now be provided with a single instance. Any component from the game down is unaware of this fact, they simple interact with a rendering component. If we were to provide a composite of rendering components the game would be unaware. This change of scope provides the benefits of a singleton. One area that has been lost is the lazy initialisation of the renderer which may or may not be an issue.

DI does not solve all problems however. Sometimes dependencies are global. The likes of date/time or logging spring to mind. In these cases alternative solutions exist.

Tuesday, 8 March 2016

Eating your own Dog Food

Also known as dog fooding. It's an odd term, with roots dating back to 70's adverts and the even more bizarre. In software development the idea is simple. Use the software you produce to make it better. This can be taken to the extreme with examples such as Notepad++ being built with Notepad++, or the Github team using Github internally. These examples mean the product is as good as it can be from real life use.

API's

Dog fooding works great for APIs. When the boundary of a system is an API building a fake test UI is a wise move. This integration acts as if you were the user. If you can solve the basic uses cases that your integrators need you can be confident the API is fit for purpose. Integration highlights problems and areas for improvement. Building a test UI is a very easy step to carry out which is also useful for demonstrating and documenting the API to others.

The danger of not eating your own dog food when producing APIs is detachment from what your users will be trying to do, versus what you implement. In many cases this means that while your API may be fully compliant with the latest standards, framework and technology, it is not actually fit for purpose. Naturally this will incur overhead when the users raise issues that need resolving, often late in the day.

Libraries

It is often tempting to extract a library for a common task. As always try to fight this urge until at least the third time. As well as this try to use the library yourself before releasing. If you can use this library in at least three places you very well may have a successful piece of software. If the answer to this question is no, the library may not be as useful as you think.

Libraries that have not been built using dog fooding are often clunky, unintuitive and frustrating to use. Every developer could name numerous examples that would fit this criteria, but the opposite is also true. The use of dog fooding tends to force libraries into the later.

Tuesday, 1 March 2016

Write Assertions First

Writing a test as part of the TDD process is simple.

  1. Arrange
  2. Act
  3. Assert

Many individuals recommend the process be reversed. Write assertions first. Then write the steps to perform the action. Followed by the required setup to complete the action.

  1. Arrange
  2. Act
  3. Assert

Simplicity

You will write just enough of the test to do the job. Its not far from doing TDD on the test itself. Using staticily compiled languages you would see compile time errors while performing this step. As you are writing the test in reverse this is normal and expected. Most text editors or IDE's can ease this process.

Implement just enough of the test to do your job. The opposite of this is large, copy/paste tests that require lines of setup code that can safely be removed or reduced.

Meaning

You end up naming variables with more meaning. With a traditional approach variables can lack true, descriptive names. They are often called result or similar. By working in reverse you force yourself to think of what you are asserting upon. This forces better names out in the process. An example would be orderTotals if the purpose of the assertion was to check if the total of an order was as expected.

Writing assertions first can feel awkward but the benefits of this change are well worth the initial slowdown.