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!