S.O.L.I.D. in Kotlin

My journey of demonstrating how S.O.L.I.D. design principles can be applied in a range of programming languages going back 50+ years gets bang up-to-date with an example in Kotlin.

Now, you could probably argue that Kotlin is a no-brainer where this is concerned. Anything I can do in Java I can do in Kotlin, if I choose to. Kotlin has classes, interfaces and constructors. We can make data private just as easily as in Java. But still, I hear objections from developers doing pure FP in Kotlin that either:

a. “OO” design principles don’t apply (which is why I’ve stopped calling them that – they’re modular design principles), or…

b. We don’t need to apply S.O.L.I.D. to functional programming, because FP is innately S.O.L.I.D. (Spoiler Alert: it isn’t.)

Whereas with older languages like C and Fortran 77, I’m working harder to get around some language limitations, with languages like Kotlin and Clojure, I’m having to work harder to get around cultural limitations. To be fair, this is not a new phenomenon. I can clearly recall programmers telling me – in the heydey of OOP in the mid-to-late 90s – that you didn’t need to think about things like modularity because OOP is innately modular. (Spoiler Alert: it wasn’t.) Give a C programmer C++ and they’ll write you procedural C++ code. And, as my previous post illustrated, give a C++ programmer C and they’ll find a way to create objects with it.

I define code that’s effectively modular by three key properties:

  • It’s made of discrete parts that do one job each
  • Those parts know as little as possible about each other
  • Those parts are easily swappable

There’s no programming language on Earth that forces us to write code that ticks all three boxes. You have to tick the boxes yourself by the design choices you make.

Granted, there are things we need from a programming language to enabe effective modularity:

  • The ability to break code up into discrete reusable units (i.e., modules)
  • The ability to control what client code can see of a module (or – in the case of Ruby, Python, JS etc – the ability to make that not matter with dynamic binding)
  • The ability to dynamically substitute a different implementation without re-writing the client code

These days, the vast majority of programming languages available to us score 3/3. There are some older languages that offer no mechanism for polymorphism, but you’re very probably not using one of them on a regular basis. You can even do it to a limited extent in Fortran 77. Any language that allows us to pass a function or procedure pointer/reference as a parameter is technically polymorphic.

Anyhoo, here we are in 2019, and the shiny new kid on the code block is JetBrain’s Kotlin. It’s a derivative of Java, with spiffy FP sensibilities. To an old Java hand like me, it takes no time at all to learn. Here’s the carpet quote example in Kotlin.

Again, the first problem that leaps out at me is that this function is doing more than one thing. It breaks the Single Responsibility principle. Let’s refactor each reason to change into its own function in its own module.

The next thing that’s bothering me is that our data classes Room and Carpet are unencapsulated. That’s always bugs me. In OO design, we say that data classes are a code smell. They hurt us in FP, too. A dependency’s a dependency. Let’s refactor our area() and price() functions into closures that hide the data from quote().

And yes, I would just as readily use a class instead of a closure. I’m not an FP purist.

This refactoring has killed two birds with one stone: we’re hiding the data from quote() and now we can easily swap in a different implementation for calculating room area and carpet price without changing quote().

For example, what about a circular room?

That ticks the O, the L and the D in S.O.L.I.D. – our dependencies are now easily swappable. So, so far, we’ve covered S.O.L.D. as well as Tell, Don’t Ask.

What about Interface Segregation? Well, unlike many languages that support FP, Kotlin also has direct support for classes that implement multiple client-specific interfaces. If we can do it in Java, we can do it in Kotlin.

Tick.

 

You can view the source files at https://github.com/jasongorman/kotlin_solid

C is for S.O.L.I.D.

In my last post, I dusted off my C skills  – it’s been a very long time – to demonstrate how we might have achieved encapsulation in C thirty years ago. (Indeed, this is how I was taught to do it by engineers who’d been working in C in the 1980s.)

That ticks one box for the software design principles I teach on the Codemanship course: modules should Tell, Don’t Ask.

What about the other design principles? Well, can we all agree that Simple Design applies in any programming language?

  • C code should work
  • C code should clearly communicate its intent
  • C code should not repeat itself (unless repeating itself makes it easier to understand)
  • C code should be composed out of the simplest parts

That leaves the S.O.L.I.D. principles from the course. Let’s go through them one letter at a time and see how (or if, or why) they could be applied in C.

 

Single Responsibility

Modules should only have one reason to change

In the example I used last time, we started with a carpet_quote module that “knew too much”. It calculated the area of a room based on the room’s dimensions, and it calculated a total price for a fitted carpet based on the carpet’s price per square metre, and whether we should round up to the nearest square metre.

What has calculating the total price got to do with how we calculate the area of the room? I can easily imagine wanting to change how we do either of those calculations independently of the other. For example, what about L-shaped rooms? What if we need to apply a discount for larger rooms? Arguably, these two pieces of logic belong in two separate modules. We split them up to help carpet_quote Tell, Don’t Ask, and here’s another good reason why we should have split them up.

 

Open Closed

Modules should be open to extension and closed to modification

In the refactored Tell, Don’t Ask version of the carpet quote example code, we ended up with carpet_quote using a room and a carpet module inside which the data and the details of the calculations were hidden. What if I wanted to extend this design to price carpets for circular rooms? carpet_quote binds directly to the current room.h header.

Whether or not I can swap in a different implementation without modifying carpet_quote.c will depend on what’s exposed in room.h.

There are two blockers here if we want the two kinds of room to co-exist in the same code: first, the “constructor” function new_room(). It’s signature would need to change for a circular room (e.g., new_room(float radius) ), and any modules importing room.h would be affected by that change.

What we need here is a clean separation of the abstractions of a room from the details of how the room is created.

So let’s define two implementations of room in separate modules, with their own constructor functions.

Note here that, because the Room struct is only implemented internally, we can implement it again in a circular_room.c file without any naming conflicts.

Rinse and repeat for a circular room.

So far, so good. But both of these modules can’t implement the area() function defined in room.h, or we get a naming conflict. How can we have two implementations of area() co-exist in a language that doesn’t explicitly support polymorphism?

The simplest solution is to use a function pointer in carpet_quote that matches the signature of area(), instead of directly invoking area().

Then rectangular_room and circular_room can have their own unique functions for calculating room area.

Now our client just needs to create the correct kind of Room and pass in the associated area calculation function.

This is, of course, nasty. We’re holding the client responsible for making this type safe. If we try to apply rectangular_area() to a circular room, we’ll get an error. How can we ensure that the right area function is applied to any room?

We’re in luck. If, in C, functions can be data, then structs can contain functions.

We can assign a reference to the appropriate area function inside each constructor.

Then we can re-write the quote() function to use the attached area() function.

Now the client doesn’t need to know anything about the area() function. It just decides what kind of room to create, as before.

This refactored design allows us to add new kinds of room (new kinds of dimensions) and new ways of calculating the area of carpet required without making any changes to the existing modules.

Yes: it’s hard work in C! But it can be done. It can be done in any programming language that supports function pointers.

 

Liskov Substitution

An instance of any type can be substituted with an instance of any of its subtypes.

This design principle is all about contracts. If we define an abstraction for calculating the area of carpet required for a room, the client will have expectations about how to use that function and what they should get from it that must hold regardless of which implementation is being used at runtime.

In practical terms, if we wrote a contract test for the area() function – e.g., when the deminsions are positive numbers the output should be a positive number greater than or equal to a “base dimension” – then every implementation of area() must pass that test.

 

Interface Segregation

Modules should present client-specific interfaces

Here we’re talking about what modules make visible to the client modules that use them. This is more important in a statically-typed language like C than it is in dynamically-typed languages like JavaScript. I guess the advice here is to make good use of .h files to control what clients see.

Taking carpet_quote.c as an example, it references room.h and carpet.h.

It needs to know about the type Room, and it needs to know a Room struct has an area() function. What’s exposed in room.h?

carpet_quote doesn’t need to know about dimensions. How could we refactor this so that carpet_quote is only exposed to what it uses? The honest answer is “not easily”. Once we’ve defined a Room struct with an area() function, we can’t redefine it to have additional features.

If we extracted Dimensions into it’s own .h file, we’d just have to include it here anyway. Importantly, the details of what Dimensions contains is hidden from carpet_quote, because we encapsulated the implementations inside rectangular_room.c and circular_room.c.

So 100% client-specific interfaces is tricky in C. But at least we can control what functions clients are exposed to through the use of header files, which gets us much of the way there. carpet_quote.c knows nothing about how rooms and carpets are created, knows nothing about what data they contain and doesn’t know about the room-specific functions for calculating areas.

 

Dependency Inversion

High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions shouldn’t depend on details. Details shoud depend on abstractions.

Putting it all together, we’ve achieved a kind of dependency inversion in the way that carpet_quote only depends on an abstract definition of a Room. The details of that room’s internal dimensions, and the way we calculate the area of carpet required to fill it, are hidden from carpet_quote. Room could be thought of as an abstract class in this sense, and implementations of are injected as an argument of the quote() function. (Or, as we did before, we can inject the area() function implementation directly. This is very similar to the way we achieved dependency inversion in functional JavaScript or Ruby in previous posts.)

The way to know if we have inverted dependencies is to examine the imports: what files does carpet_quote.c need to include?

Aside from its owner header file, it only imports the abstractions in room.h and carpet.h. This high-level modules doesn’t depend on low-level modules, nor does it depend on details.

When we use dependency injection to wire our collaborating modules together, the tendency is for the details – the dependencies on implementations – to bubble to the top of the call stack. Good modular architectures wear their implementation dependencies on the outside.

Examining the imports in main.c, this appears to be exactly what has happened.

We might then go through a similar process to abstract the way that carpet price are calculated. (I’ve left this for you to do.)

 

So there you have it. S.O.L.I.D. – for the most part – can be applied in C. And, back in the day, I routinely applied it when C++ was not an option. If you’ve got function pointers, you can SOLID.

 

You can view a complete copy of the finished code at https://github.com/jasongorman/solid_c

Tell, Don’t Ask in C

I’m preparing a keynote on “Timeless Design Principles”, with the aim of demonstrating how the principles I try to instil in developers on my Codemanship courses could have been applied just as readily 30 years ago or even 50 years ago in programming languages of the time.

In 1989, C ruled the world. A common misconception among inexperienced developers is that design principles like S.O.L.I.D. and Tell, Don’t Ask only apply to OO languages like C++.

Nothing could be further from the truth, though. Let’s start with Tell, Don’t Ask.

Consider this simple C function that calculates a quote for a fitted carpet:

The quote() function has to ask for the room’s dimensions, and then has to ask for the carpet’s price pr square metre and whether it should round up to the nearest square metre.

Although Room and Carpet aren’t classes, as far as I’m concerned this is still Feature Envy. Room and Carpet are completely unencapsulated. The carpet_quote module knows how the area of a room is calculated, and it knows how to calculate the price of the carpet in that room. If those details change, carpet_quote breaks. Or, more simply, carpet_quote knows too much.

A good first step to fixing that would be to move those two pieces of logic into their own functions.

Now our quote() function knows a lot less. But the carpet_quote module still knows it all. So the next step would be to move the area() and price() functions to the modules where the Room and Carpet structs are declared.

carpet_quote now knows less about the details, which are neatly encapsulated inside carpet and room.

The data is still accessible from the outside, though. So we’ve got a little more work to do to complete this refactoring. At the moment, the Room and Carpet structs are declared in completeness in the header files room.h and carpet.h, so any module can create and set their field values directly.

In our client code, we instantiate these “objects” directly, setting their field values externally. This gives me the screaming heebie-jeebies. (Every bit a smuch as “data classes in Python, or JSON objects in JavaScript.)

How can we hide the data of a Room and a Carpet inside their respective modules? Luckily, C gives a mechanism: partial declarations. We can partially declare a struct in a .h file, defining its type but omitting its data.

Then we can declare the struct with all its data fields in the .c file, so that they can only be accessed internally. Then we add a factory method – essentially a “constructor” – for that type.

Now the only way a client can get a handle on an instance of the struct is via its module, and it can’t access the data directly.

 

Refactoring To Higher-Order Functions

In my last post, I demonstrated how we might refactor a simple object oriented piece of code into a functional style with a JavaScript example. The focus of that example was about how to get from instance methods that access mutable fields to stateless functions that use immutable data structures.

I wanted to follow that up with a slightly more sophisticated example to illustrate how we might refactor from an OO design that uses dependency injection to an FP design that uses higher-order functions.

Let’s do it in Ruby this time.

Here we have a class that writes customer data in a variety of formats – XML, HTML and andstrings – to a variety of output destinations – console, log file and NoSql database.

The serializers all present the same interface, with a write() method that accepts a customer parameter. A good first step might be to pass in lambda that invokes the serialize() method instead of invoking it on the serializer instance inside write().

So far, so ugly. Next we can make all our serialize() methods unique.

Then we can clean things up by turning these instance methods into standalone functions. e.g.

…allows us to re-write the client code more cleanly.

We can rinse and repeat for the output writers. Start by passing in lambdas that invoke their write() methods.

Then make each write() method unique.

Now, the next part is a little fiddlier. We want to turn these methods into standalone functions. For the console writer, it’s simple because write_console() is stateless, so we don’t have any fields to worry about.

But write_logfile() and write_nosql() access fields that are set in constructors. In the previous post, I illustrated how we can refactor from there. All the information those methods need can be passed in as arguments.

Now we can make them standalone functions.

And a final bit of tidying up: if we turn our write_logfile() and write_nosql() into closures, with the outer functions acepting all the messy extra parameters, we can simplify our client code.

Last, but not least, we get rid of the ResponseWriter class, making its write() method a standalone function.

 

 

 

 

 

Refactoring to Functions

While I’ve been porting the Codemanship Software Design Principles code examples to JavaScript – in both OO and FP styles – I’ve been thinking a lot about the relationship between those two programming styles.

Possibly the best way to illustrate might be to refactor an object oriented code example into a functional example that’s logically equivalent. This might also serve to illustrate how we might move from one style to the other in a disciplined way, without breaking the code.

This is the simple class I’m going to start with.

And these are its tests.

The first refactoring step might be to make each method of the class properly stateless (i.e., they don’t reference any fields).

To achieve this, we’ll have to add a parameter to each method that accepts an instance of BankAccount. Then we replace this with a reference to that parameter. This will work if the BankAccount we pass in is the exact same object this refers to.

So, in our tests, we pass in the BankAccount object we were invoking credit() and debit() on.

Now we can pull these instance methods out of BankAccount and turn them into global functions.

The tests can now invoke them directly.

One last piece of business: the BankAccount data object. We can replace it in two steps. First, let’s use a JSON version instead that matches the schema credit() and debit() expected. To make this the smallest change possible (so we don’t have to re-write those functions yet), let’s make them mutable.

Then we can re-write credit() and debit() to return mutated copies.

This will require us to re-write the tests to use the mutated copies.

So, there you have it: from OO to FP (well, functional-ish, maybe) for a simple class with no collaborators. In the next post, I’ll refactor some a code example that involves several related classes so we can examine the relationshi between dependency injection and high-order functions.

 

Tell, Don’t Ask in Functional Programming

In my last blog post, I illustrated how S.O.L.I.D. design principles can be applied to functional programming with five JavaScript examples.

There’s more to modular design than SOLID, though. For example, what about encapsulation?

As I continue to port the Java and C# examples for the Codemanship software design principles course, I’ve reached Tell, Don’t Ask. Take a look at the example code for calculating how much to charge for a new carpet.

Here’s the thing about functions: when they act on data structures (like JSON objects or tuples), the relationship between data and the logic that acts on that data inherently becomes unencapsulated. That’s just a fancy way of saying that carpet_quote.js knows too much. It knows how to calculate the area of a room based on the length and the width. It knows how to round up the area of a carpet if required. And it knows how to combine these things to get a price for that carpet in that room.

How could we encapsulate each of these jobs so that carpet_quote knows less? The answer may lie in closures.

We can encapsulate calculating the area of a room inside an outer function that takes the length and width as parameters.

And we can encapsulate the knowledge of calculating the price for that area of carpet inside an outer function that takes the price per square metre and whether or not to round up to the nearest square metre as parameters.

Then we can rewrite quote() as a higher-order function (just a fancy way of saying “inject the functions it uses”) that knows a lot less.

The data required is no longer exposed to carpet_quote. Instead, it’s passed to the outer functions of the closures in the client code – acting effectively as constructors. (Yes, closures are a lot like classes, dontcha think?)

Each module now only has one job, and has no direct implementation dependencies. And it makes the logic of calculating room areas and prices swappable. This design ticks all three boxes of good modular design:

  1. Each unit does one job
  2. Each hides its inner workings (especially its data)
  3. Their dependencies are swappable (by injection)

Let’s say we wanted to calculate the areas of more complex rooms (e.g., L-shaped, circular). In the refactored design we can extend the solution without having to rewrite carpet_quote. So this design is S.O.L.I.D., too.

 

If you’d like to have a crack at refactoring the JavaScript design princples examples, you can find the source code at https://github.com/jasongorman/JS_design_principles

Functional S.O.L.I.D. Explained In 5 Examples

I’m in the process of porting the Codemanship course materials to Python and JavaScript. After I did the S.O.L.I.D. examples from the Software Design Principles workshop in JS, I thought it might be useful to illustrate how these “object oriented” principles can be applied to a more functional style of programming.

Single Responsibility

“Classes should have one reason to change.”

The rationale behind the SRP is simple: editing classes risks breaking the code in them. Once code is tested and out there working, we’d ideally prefer to leave it that way. If a class contains code that changes at different times for different reasons, the risk is of breaking code that really didn’t need to change just because it’s in the same class as code that did. (There’s another, much more compelling reason for our classes – and methods and functions – to do only one job, which is explained on the course.)

But “class” is a red herring here. Really, it’s sources files. (Or modules.) Editing code in a source file risks breaking other code in the same file.

For example:

Here I can easily imagine wanting to change the XML output without changing the logic of a bank transfer. This module has two reasons to change. So we should split it up.

Open-Closed

“Classes should be open to extension and closed to modification”

Once a class is tested and released, modifying it risks breaking it – and any code that depends on it. A safer way to add functionality to an existing system is to extend the existing code without editing it.

This means our code needs to be designed in a way that makes extending easy. Now, this design principle arguably belongs more in the days of C++ and a few other statically-typed languages where, if you want a class to be open to extension, you have to design it a certain way (e.g., any methods you plan to override need to be declared as virtual. The love for pure interfaces for everything was born of this era.)

In the modern era of dynamic languages and duck typing, it’s very easy to swap one implementation with another – provided the client hasn’t directly referenced that implementation (which is what the D in SOLID is all about.)

Back in the day, we no doubt had inheritance in mind. But that has very much fallen out of favour in recent years, and now many developers prefer composition instead. A subclass that presents the same interface as a base class, and delegates method calls to an instance of the base class internally is logically the same as implementation inheritance.

The functional equivalent of that would be a function with the same signature as the “base” function that internaly delegates to it.

Imagine we wanted to extend a function for borrowing videos from a library so that we can prevent people from borrowing titles they’re too young to see:

All we have to do is create a new function that has an identical signature, that calls the original borrow() function.

Liskov Substitution

“An instance of a class can be substituted with an instance of any of its subclasses”

The example above solves the problem of syntactic swappability of a function with an extended version that has the same signature. But… it’s not quite as simple as just syntax in many cases of extension.

First of all, you may have noticed that the extended function relies on customers having an age, and videos having a rating. We didn’t just extend the function, we extended the data structure (in this case, the JSON object) the function accesses. Any client passing in the old data structure will cause an unhandled exception.

Also, the client could be in for a nasty surprise if the customer is too young for the video they’re borrowing, in the shape of an unexpected error. We’d have to rewrite the client code. Ths is how ripples start in our code that can spread from the module we changed/extended to the rest of the code, making even the smallest changes very expensive.

Ideally, we want to be able to extend the software without having to rewrite client code. And that means, in practice, that – as far as existing clients are concerned – the contracts for calling functions must still hold.

The original borrow() function has no precondition. Any customer can borrow any video. The extended version requires the customer be old enough. So there are scenarios for using borrow() the client thinks are valid that no longer are. (Imagine turning up to the airport with your ticket and your passport, and not being allowed to board the flight because, on your way to the airport, they added a requirement to bring the pilot a bunch of bananas.)

Consider this simple bank account module:

We’re asked to extend it so that customers can withdraw beyond the balance up to an agreed overdraft limit. In an FP style, this just means “overriding” the debit() function.

So far, soo good. This works syntactically. Anywhere clients expect the original debit function, we could substitute the new version. But have we broken the original contract?

One way to check would be to somehow run the original bank account tests against the new implementation. Right now, they look like this:

As they are, it’s not possible to swap in the new implementation because the tests directly reference the old one. What if we refactored the tests to look like this?

Now we can run the same tests with two different implementations of debit(), and two different versions of the account object. Now, I wonder what happens when I run these tests…

 

Interface Segregation

“Classes should present client-specific interfaces”

Back in the days when C++ ruled the world, if I changed a class’s interface (e.g., renamed a method), all the code that referenced that class had to be recompiled, re-tested and re-deployed. Unavoidable if those clients use that renamed method, but totally avoidable if they don’t, by extracting interfaces that only include the methods they actually do use.

In FP, there are no interfaces. Or, rather, every funtion can be thought of as an interface with only one method. Add to that dynamic binding, and the problem goes away. So, arguably, a discussion about Interface Segregation is moot.

But in the heat of battle, as functions evolve and move between modules, and dependencies change, it’s entirely possible for one module to end up directly referencing functions and modules they no longer use. The effect is the same.

Although this module only uses the rating() function from book.js, it references two other exported functions. If I were to, say, move summarize() to a different module, this code breaks.

So, in FP, we might re-frame Interface Segregation as:

“Modules should only reference things from other modules they actually use”

Dependency Inversion

“High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should depend on abstractions.”

This is a rather hifalutin way of saying that dependencies between modules should be swappable.

Consider this example:

This is a poor design. How do we add new kinds of output format without modifying this write() function? That breaks the Open-Closed principle. OO languages give us a simple mechanism for making choices without the nastiness of enums and conditionals: polymorphism.

FP gives us exactly the same mechanism. Two functions with the same signatures can be invoked by the same client, without the client knowing which implementation it’s using. From the outside, they look exactly the same.

If we refactor write() to remove direct references to the implementations, and inject the output function from the outside, we can make that dependency easily swappable and our design easily extensible.

Now the client decides which output function to use:

Notice that all the implementation references are at the top of our call stack now. This is the effect that composing functions (and objects in OOP) by dependency injection tends to have.

Dependency Inversion (and dependency injection that enables it) is as much a foundation of good, extensible FP as it is of good OOP. You may have noticed how many, many staples of the FP paradigm – e.g., map(), filter() and reduce() – work by allowing us to pass in functions that are invoked inside without having to anything about the function being called other than its signature.

 

So there you have it: S.O.L.I.D. applied to functional JavaScript in five examples. If you want to take a more detailed look at the example code and try the refactorings for yourself, it’s all on https://github.com/jasongorman/JS_design_principles

And if you’d like Software Design Principles training and coaching for your team, you know where to find me.

 

S.O.L.I.D. JavaScript – OO Version

A little while back I wrote a post on the old blog about how we could apply the same design principles – near enough – to functional programming as we might to object oriented programming, using JavaScript examples.

That encouraged a couple of people to get in touch saying “But we don’t do FP in JavaScript!”, and suggesting therefore that – strangely – these principles don’t apply to them. The mind boggles.

But, for completeness, here’s how I might apply S.O.L.I.D. principles to OO JavaScript code. To make things backwards compatible, I’ve not used the class syntax of later versions of JS.

First of all, the big tomale: swappable dependencies (Dependency Inversion).

Consider this snippet of code for a simplistic shopping basket:

The problem here is what happens if we want to change the way we process payments? Maybe we don’t want to use PayPal any more, for example. Or what if we don’t want to use a real payment processor in a unit test? In this design, we’d have to change the Basket class. That breaks the Open-Closed Principle of SOLID (classes should be open to extension, but closed for modification.)

If we inject the payment processor, then it becomes easy to swap the implementation for whatever purpose (in this example, to stub the processor for a test.)

And there we have it: three fifths of SOLID is about making dependencies swappable – Open-Closed, Liskov Substitution and Dependency Inversion. (or “OLD”, if you like.)

And can we agree classes should have a Single Responsibility? That’s not really an OO principle. The same’s true of functions and modules and microservices and any other discrete unit of executable code.

Finally, the Interface Segregation Principle: classes should present client-specific interfaces. That is, interfaces should only include the methods a client uses. With duck typing, it doesn’t really matter of a class presents methods a client doesn’t use. This is true whether we’re talking about methods of classes, or functions in modules.

It might help to make the code easier to understand of we document protocols by explicitly defining pure abstract classes that describe what methods any implementation would need to support. But it’s not necessary for our code to compile and run.

But, as with the functional examples I used, there is a case for saying that modules shouldn’t reference implementations they’re not using. Let’s suppose that after I refactored my Basket to use dependency injection, I forgot to remove the import for PayPalPayments:

It’s important to remember to clean up your imports regularly to avoid situations where changes to things we don’t use could break our code.

So, the sum up: the same principles apply in JavaScript regardless of whether you’re doing FP or OOP.

No excuses!

It’s The Culture, Stupid!

We’re just four weeks away from Codemanship’s 10th birthday, and this might be a good time to reflect on how and why I started my developer training business, as it may hold clues about where Codemanship might go in the next ten years.

When I started the business, I’d been a professional software developer for 16 years. For the majority of that time I freelanced, working for a wide range of companies on a wide range of business and technical problems. Along the way, I progressed into leadership roles, and found more and more of my time being spent coaching and mentoring teams  – with varying degrees of success. I also wrote and delivered training for a number of companies, so Codemanship wasn’t my first rodeo in that respect.

I’d attempted to make the transition to full-time training and coaching several times, but the dice never quite fell where I needed them to. It takes time to build up a business: to build a reputation, to build a client base, to build a livable income. And it’s very difficult to do that while you’re holding down a full-time job at the same time. I would typically try for 6-9 months, and then wimp out and go back to contracting.

The opportunity I needed fell into my lap in 2008. I was finishing up a contract with BBC Worldwide as a  – and this was my official title – Software Development Coach. Whereas before, that side of my work happened “between the gaps” as I led dev teams, when time and resources allowed, now it was my full-time job. With the blessing of the management, I was there to help teams do dev better.

bbc_mattwynne
Matt Wynne shares ideas in a goldfish bowl session at BBC Worldwide

Alongside my permanent counterpart, Peter Camfield, we coached teams on what we might now call the “craft” of writing software. And over the course of a year, we saw some quite dramatic changes. It’s easily the most satisfying experience I’d had up to that point.

I get a real kick out of seeing dev teams being empowered to do great work, out of seeing the level of enthusiasm for and pride in their work rise, and out of seeing how so many of those great folk have gone on to inspire a good many developers themselves: people like Matt Wynne, Rob Bowley, Julian Everett and Hibri Marzook, who are today valued contributors and influencers in the developer community.

bbc_hibri
Hibri Marzook participates in an Agile planning game

The experience at BBC Worldwide was, I now realise, very atypical, even though tech there was pretty typical of most organisations of that size. They had the people, they had the talent. It was there all along. All that was needed to set fire to this “kindling” was a suitable catalyst, which – it turned out – was me and Peter. Once we got the fire going, it burned all by itself.

I was fresh off a contract that, on paper, gave me the exact same goal. I had been working as a “Development System Architect” for a large software company, as part of a team that was charged with defining and imposing development processes and practices. This was very much CMMi territory, and I’d been hired for my uncanny skill at drawing boxes connected by arrows and my encyclopedic knowledge of arcane dev processes that no team anywhere has ever actually followed.

bbc_gojko
Gojko Adzic visits BBC Worldwide to give a talk on Specification By Example

We produced reams of documents telling developers how to do their jobs, which, of course, nobody ever read. Sure, we had the full backing of the VP of Engineering. But that made no difference. After one year, nothing had changed. Nothing had improved. And this was by no means the first time I’d seen that happen…

I had decided – after years of watching top-down attempts at software process improvement fail to deliver meaningful, lasting change – to try doing something bottom-up; to water the roots instead of the canopy of the organisational tree. This, it turned out, was far more successful.

bbc_ericevans
Eric Evans plays the piano before his talk on Domain-Driven Design at the BBC Club

Instead of prescribing processes and practices from above, we started with the developers themselves and what sort of things got them fired up. More simply, we ignored the “system” and focused on the culture.

It started small, with regular lunchtime meet-ups where developers were invited to come along and talk about any topic they thought interesting. Eight people out of a department of roughly 100 came to the first one. That might sound like a failure, but I’ve come to realise that if you can find eight people in your IT department who would give up their lunch to share their ideas about software development, that’s something you can really build on: a solid foundation for change.

bbc_martinfowler
Martin Fowler defeats the Daleks yet again before his talk “Software Design in the 21st Century”

The audience grew each session, and for many it was their first experience of talking in front of other developers. By the time I moved on, pretty much everyone in the IT department went. And quite a few folk from BBC corporate, too. We had some big talks by some very well-known speakers in some pretty large rooms.

Sure, there was a bit of training, and a lot of coaching and mentoring from myself and Peter for the teams that invited us in. But I firmly believe that wasn’t what made the difference, in the long run. What made the difference was that dev teams found themselves working in a more inspiring, energizing environment. They were thinking about this stuff, and – most importantly – talking about this stuff. They didn’t need to be told to do it. They wanted to do it.

bbc_petercamfield
Peter Camfield, Dan Rough and Josh Chisolm celebrate the fact that I’m leaving

And then, like all families, some of them eventually flew the nest and spread that enthusiasm and inspiration far and wide, to companies like 7Digital, Songkick and the Co-op, to OSS ventures like Cucumber, to meet-ups and conferences like Software Practice Advancement, and the original Software Craftsmanship conference (in fact, the first one was hosted by the BBC). Some of that BBC Worldwide DNA can be found imprinted on businesses and teams and communities all around the world. For example, the list of “good habits” of TDD originated there.

bbc_sc2009
Keith Braithwaite debuts his “TDD as if you mean it” workshop at SC2009 at the BBC

I’ve seen this effect before in other companies, like ThoughtWorks and Google. It’s not their “development system” that makes the difference; it’s their developer culture. If you want talented teams of inspired engineers doing their best work, focus on building a strong developer-led culture in your organisation. You don’t need to make them. Just let them.

My experience at BBC Worldwide in 2007-2008 was so rewarding that I genuinely dreaded going back to the same old same-old on another gig. As it happened, the next contract was one of the least satisfying of my career; trying to deliver working software to a difficult client in difficult circumstances with micro-managers bearing down on us and totally unrealistic expectations. That made up my mind: I was getting too old for that shit.

The relationship I’d built with tech teams across the road in BBC corporate offered an “out”. They wanted training and coaching from the guy who organised all those spiffy lunchtime talks they’d been going to. It was enough work for a few years to allow me to focus exclusively on that, and build the client base Codemanship enjoys today.

Sure, it’s a small business, and in the grand scheme of things I make a small difference. But it’s immensely satisfying. Nobody was going to offer me my dream job, so I invented it. And ten years later, he we are.

And, because it’s my company, we do things on my terms. This isn’t corporate, top-down intervention. Typically, I’m not there because the CTO wants me there. (Quite often I’m there despite the management’s wishes!) My work begins and ends with the developers. They ask for the training – sometimes they have to beg and stamp their feet to get it, of course – and it’s 100% training for developers, written by a developer, and delivered, with a big dollop of developer rabble-rousing and advocacy, by a developer.

And I never forget: when it comes to meaningful, lasting change… It’s the culture, stupid!

 

When Do We Learn?

whendowelearn

It’s always interesting when something you post on social media seems to chime with what a lot of people think. Yesterday, I posted this:

Judging by the likes and retweets, as well as the replies and comments, this is a debate many of us have had.

I’ve posted many times before about how most employers of software developers have an expectation that we arrive fully formed with all the skills and experience they need. They make little time and offer little support for learning as part of the job. This is one of the underlying causes of the so-called “skills crisis” in our industry: employers will wait to find someone with Java 9 experience, but won’t wait for someone with Java 8 to get up to speed.

But be absolutely sure: learning is part of this job. Arguably learning is the job. We’re innovating all the time, and that implies that we’re continually solving new problems and continually learning. It’s one of my fundamental principles of software development: it’s a learning process.

If you condemn developers to learning entirely by trial and error, with no input from other, more experienced developers who’ve “been there, done that and got the t-shirt” – whether it’s in person, from books, from blogs, from videos – then a great deal of their time – and your money – will be wasted making all the same mistakes all over again.

And if you give them no time to learn and adapt from their own mistakes – through retrospectives, root cause analysis, Kaizen and the other continuous improvement activities – then you condemn your dev teams to perpetual Groundhog Day, doing everything the hard way, again and again and again.

The smart dev organisations make time and space and assign resources to learning, sharing knowledge and continuously improving. It could be through ongoing training (pretty rare),  or dedicated 10-20% time for teams to learn, experiment and improve (very rare),  or structured long-term mentoring (vanishingly rare).

Many organisations expect these things to happen outside of working hours, in the developer’s own time. Indeed, many developers expect that, too. It’s a regrettable fact in this industry that if you want to learn and progress, you will probably have to invest a lot of your own time, energy and money into making that happen. This is bad news for us all when potentially great developers, with bags of smarts and heaps of aptitude, also have tonnes of outside commitments – young children, elderly relatives, volunteering in their communities, or just generally having a life outside of software.

When the signal goes out, loud and clear, “If you want to be successful as a software developer, forget having a life”, we shouldn’t wonder why the profession lacks diversity.

How do we change this? I’ve said this before, but it bears saying again: the time and resources for continuous learning will not be freely given, even when we know it’s in the best interests of employers. We must take it.