Software Architecture

Reflections on 15 years of Growing Software Guided by Tests

About the episode

Share on:
linkedin facebook
Copied!

Growing Object-Oriented Software, Guided by Tests (GOOS)

Duncan McGregor: Hello and welcome to "GOTO Unscripted." I'm Duncan McGregor. I'm a professional software developer based close enough to London to make a living. I started programming computers on a ZX81 when I was 13. I've been lucky enough to ride a wave of demand for developers that started in the 1980s and has continued throughout my career.

I first met Nat Pryce in the early 2000s when we were both members of the Extreme Tuesday Club, a meet-up for developers practicing extreme programming, one of the precursors to agile development. Nat Pryce and I recently wrote a Kotlin book together, but up until that career highlight, he was best known for the book he wrote with Steve Freeman titled "Growing Object-Oriented Software, Guided by Tests," but colloquially known as GOOS. The book was published in 2009 in the Kent Beck Signature Series and was highly influential in the then relatively-infant agile movement. It is still at number 402,655 in Amazon rankings.

Nat Pryce: It's that good?

Duncan McGregor: I don't know.

Nat Pryce: It's a number.

Duncan McGregor: It's a number. Nat, for those in our audience who were still at school when GOOS was published, what's it about?

Nat Pryce: That makes me feel old. It's a book about test-driven development and was written to encapsulate everything that we had in the Extreme Tuesday Club...so it wasn't just me and Steve inventing it. We were the six...let's talk about the Extreme Tuesday Club and then I can talk about GOOS.

The Extreme Tuesday Club was an informal meetup. It's still going to this day, but it started in the early 2000s, people in London who were interested in extreme programming as it was very new when the sort of meetup started. And it was being publicized on the C2 Wiki and people were really quite inspired by this new way of development that was being publicized by Kent Beck, Ward Cunningham, and people like that, Ron Jeffries, and stuff.

So a bunch of interested people just arranged a meetup in a pub in London. It went from pub to pub. It grew over time. It spawned a bunch of conferences that then ended up spreading around the world. And it also spawned a lot of different technical techniques that people learned and shared and sort of developed in their work and then shared in that sort of meetup.

So GOOS was us writing about test-driven development and the techniques that had been shared and invented within the Extreme Tuesday Club along with...sort of portrayed as by a long-worked example that was an auction-sniping sort of application that would try and buy things on, I think eBay was quite new at the time, so on something like eBay, and how do you write that in a test-driven development way.

A bit different from probably applications now in that it was a desktop application and it communicated with a protocol that doesn't exist anymore or no one really uses. But a lot of the principles still apply and we showed how you would start from writing a test, writing a test of what the system should do. The system would start off very unstructured because it was very small and didn't need any structure, and then you'd add more and more tests. And as the system grew and you wanted to test various bits more thoroughly, you would have to work out how to carve out those parts and mock bits of them while you sort of thoroughly test other parts. And over the narrative arc of the example at the end of it, you see how the final result is that the hexagon architecture sort of emerges from the continual refactoring and the pressure of the need for testing the application.

Recommended talk: Tidy First? A Daily Exercise in Empirical Design • Kent Beck • GOTO 2024

The Extreme Tuesday Club and Extreme Programming

Duncan McGregor: I only relatively infrequently came to XTC. But I do remember the first time I ever did come, Kent Beck turned up, and I just expected that was normal for London. After that, everything went downhill a bit.

Nat Pryce: Thanks.

Duncan McGregor: I do remember that we...extreme programming, which people may or may not know, right? These days I don't think it's fashionable. Extreme programming was one of a few precursors, one of a few ways of writing software that ended up under the umbrella of agile. I think XP in particular was developer-focused, wasn't it? I mean, we'd have Scrum, which really didn't talk about what developers should be doing most of the time, whereas XP was a thing that told developers how they should be working. It told us that we should be doing pair programming. It told us that we should be writing tests first. It had a bunch of principles and a bunch of practices. But the whole TDD thing I think was the big difference between XP and just other methodologies.

Nat Pryce: There was a whole bunch of agile methods very early on. So you're saying like about luminaries turning up at XTC. So Alistair Cockburn turned up a few times and he was a methodologist at IBM who studied how people wrote software and then captured that in a bunch of methods that he called Crystal. Crystal Clear is a very lightweight method, very similar to XP, but less prescriptive. And then he had a bunch of other methods in the Crystal family for, like, larger and more critical projects.

I think all the early agile processes definitely said something, apart from Scrum. They definitely said something about how people should write software. XP was more extreme than others. It definitely had, like, you follow these rules, these practices, and they mesh together to allow you to evolve and rapidly change your software, and that's certainly my experience.

But early on in the days of agile, I don't think it was a developer-focused process but more that agile was seen as a holistic thing. The way you should develop software has to involve the developers and the people who want the software working together with their expertise and guidance coming from different parties involved in a common enterprise. And it's only later that we end up with what we see described as agile today, where it's mostly a management process and it says very little about how you should write software. And if software development gets done at all, it's sort of not really talked about very much.

Recommended talk: From Objects to Functions • Uberto Barbini & Duncan McGregor • GOTO 2024

Developer-Led Agile vs Management-Led Agile

Duncan McGregor: My recollection of those days is that XP, in particular, was a thing that developers wanted to be doing. Like, we would go to the management and say, "Hey, look, we've been trying this stuff and it works. Can we run projects this way rather than a thing where we are brought into a project that is run by a Scrum Master?"

Nat Pryce: Yes. And I think especially in London where a lot of that was happening inside banks and other companies, it was internal product development teams or internal project teams just adopting it because it works. And there wasn't quite a strict hierarchy in those teams of product owners then Scrum Master and that, right? And those teams were arguing with their project management and maybe IT management in order to change their process, but also they could have quite a lot of leeway in the way they did things so they didn't have to say, "We're going to write tests first. Can we do that?" They just wrote tests first. Or, "Can we do pairing?" They might just sit there next to each other and do some pairing. So again, it depends on company by company. They're all different.

Duncan McGregor: XP had the role of a coach and had the role of a customer and then the role of developers. And that felt very different, to me at least, from this role of a Scrum Master who is, you know, masterful, telling us what we should be doing and a product owner who's owning this stuff that we're not owning because we're only developers.

Nat Pryce: Yes. Certainly the most sort of happy XP projects that I was on in those days, the developers often had very deep business knowledge, right? You know, financial knowledge, so you didn't have to keep going to a product owner and saying, like, "What should this do? What should that do?" You know, these people knew what particular, I don't know, derivatives or fixed income instruments or whatever did and how to process them. And that was because everybody in the organization knew that stuff, right? There wasn't such a distinct division of responsibilities. And also in other places that we've worked where people, you know, there were people who were guiding the product, product directors, but developers are allowed to say, "Hey, wouldn't it be great if the product did this?" And it was much more flexible in this sort of division of responsibilities. And I think Agile and XP works very well there because you are all working together as one team without those strict roles.

Duncan McGregor: The best project, in my experience, we have somebody that wants the software that knows what they want and knows that domain of things, and in the best teams, they see it as their job to teach the software development team that stuff and the software development team see it as their job to teach the people who want the software how to manage a software development team.

Nat Pryce: Yes. I think what struck people about XP when they first read about it was that it's, this is a way of working in teams that matches the way that I work when I'm writing software by myself, maybe with some more strict discipline around testing and test driven and refactoring. But if somebody is in charge of their own software, then they're staying on top of it. We used to call it tidying or something. But they're constantly refactoring it because they need to stay on top of the complexity because it's their own project and they've only got one brain. And within teams, this XP process took the same approach. You have to stay on top of the complexity, it's the only way to stay flexible.

The other things that were very innovative about it, at the time, was...I think at the time, so this is like, well, late '90s, early 2000s, we'd gone through a period of where teams got stuck in analysis paralysis. No one talks about that anymore, right? With the web and things like that, people can roll stuff out all the time. But back in the day, people would spend months, years doing analysis. I remember joining one area of a company where there'd been this huge effort to sort of come up with some design. This program had been running for ages. It created huge schemas that were so big that they had to buy a special, massive plotter to be able to plot them out and then stick them up on the walls. But at no point had they ever written any software at all. It was just a database schema. They hadn't even tried to make it in DDL and then put it into a database. Then after 18 months or 2 years or something, eventually management pulled the plug and no software had even been written.

So that's a kind of project approach that XP was in total diametric opposite of and that we took in the GOOS book as well. Start with a walking skeleton, make it do as little as you possibly can get away with, get it into production, get that past to production, automated, tested, you know, and then you know you can write the next bit and the next bit of functionality knowing that it's covered and tested and going into production, integrating with whatever environment it has to integrate with. And you're making these tiny, tiny steps of constant incremental and iterative improvement to the system, deported by tests. And you're using the tests for feedback about whether design needs to change and adapt and evolve.

That was very controversial at the time. And I don't think really people probably now realize quite how controversial it was. People say, "This is nothing but hacking. It's cowboy coding. This is dreadful. I wouldn't. You know, so unprofessional." Well, now a lot of those techniques are so embedded in the way a lot of people expect to work, we forget that someone had to actually sort of come up with them and publicize them.

Outside-In TDD vs Bottom-Up TDD Approaches

Duncan McGregor: My recollection of the time was that the thing that GOOS introduced us to, wrote about what maybe we'd been doing in London as part of the way we worked was a sort of outside-in acceptance test-driven approach. Would you say that was the major innovation?

Nat Pryce: I don't know if it was an innovation. It was certainly what we wrote about and it wasn't what Ken Beck really wrote about as much in his book. There was a lot more bottom-up sort of approach in TDD in the first wave, let's say. I don't like the sort of Detroit versus London school or whatever I think. But there's definitely people who start in the small and sort of grow it out. And we took a sort of "Let's try and capture everything and work from outside in." So I don't know whether that just was a result of the systems we were building that had to integrate with large sorts of IT estates and big organizations.

Duncan McGregor: So maybe you should explain. Detroit was based around the original XP system, wasn't it? Which was a payroll system for Chrysler, I think.

Nat Pryce: Chrysler, I think.

Duncan McGregor: And their TDD was a process where you sort of had this idea for what the low-level building blocks of your software would be and you'd write those and you'd write the test for them. And then you'd say, "Okay, well, now we've got this, we can build bigger abstractions based on those and then write tests and then write those." And then we build software from things that we thought, when we finally plug them together, we'll make our working software. Whereas GOOS said, "Well, there's a danger that we're going to write software that we don't need or we'll overwrite it and so on. What happens if we wrote from the outside in and wrote the very minimum set of things that we would have to write to support a particular use case, to support the next feature we're trying to do?"

Nat Pryce: I don't know whether that description of Detroit is accurate or not. I can't imagine it is. I can't imagine that they sat down and went, "Well, we obviously need, I don't know, a money-type. So we'll write money. Okay, now we obviously need a currency-type. And eventually, we'll get to a payroll." They must have started at a higher level than that.

But certainly in the case of we were working in organizations, particularly some of it came out of banks, some of it came out of telcos, where we were integrating with messaging systems that allowed us to interact with other parts of the organization. And we were integrating with, say, reference data services. So there was a definite, like, there's certain ways you have to integrate. Otherwise, you cannot make your application work. So there's clear boundaries. You're writing a system with clear inputs and outputs that you're going to plug into. Like, even with the front ends, we would treat that as sort of an input-output.

From that, you can say, well, if we want to, I don't know, order a broadband line or something. "Well, you're going to get a message from the telco that looks like this. And you're going to have to basically ask for payment from that system over there. That's going to look like that." So from there, you can easily say from the very outside, "Here's what we'd expect to see." And then start thinking about, okay...and then the admin user would see this coming up in a report. Like, you know, a person would see this coming and then start, like, coming up with a structure for those edges. And then you could build up the middle. As long as you've got the edge defined, you can refactor as much as you like in the middle, confident that you're not going to break the system.

Mock Objects and Testing Techniques

Duncan McGregor: So you've managed to not talk about one of the innovations of GOOS and sort of skirt around the edges of it. So if we're going to build a system from the outside, there's going to be this point where, for example, we have a bit of the system that we haven't written yet, but we still want to see whether our whole system works. So that system might be how we save things to disk or how we talk to this system over here or that sort of thing. GOOS publicized, popularized a technology, should we call it, of mock objects.

Nat Pryce: Practice. Technique. Yes.

Duncan McGregor: Technique.

Nat Pryce: I think it's more of a technique than a technology, I think. Because you don't need to use a particular library or something. It's really, yeah, it was used in a number of ways. So again, a lot of what we were building was event-driven or message-driven. And so it was a very natural fit for object-oriented systems built out of...composed out of state machines. So those state machines fix through states receiving and sending messages, either driven by messages coming in from a message bus or from other object message calls.

Those protocols, by which they talk, are really the design of the system. You've got a bunch of different protocols between your objects. You can then write an object in your class that implements some roles in these protocols, and then it will plug in into the right place. You can then... As soon as you've got enough of that, you're now writing code by reorganizing graphs of objects rather than writing procedural code in Java or whatever it is.

So how do you represent those protocols and how do you represent them in tests? That was one of the sort of drivers of mock objects. And how do you know if these things are clicking through states? But the way that they expose their behavior to the rest of the system is by sending out messages to other objects, not by exposing data that is queried. How do you know whether they have performed the behavior that they should perform when you plug them into that graph of objects? So again, that's where mock objects came from. How can you test drive some software without just looking at its internal state, which is an implementation detail in a system that is based around state machines composed together through messaging protocols?

Duncan McGregor: So it's odd that, in those days, we had beautiful OO design for things. And in those days we had objects whose job was to encapsulate state. That we weren't supposed to ask about the state, we were supposed to derive interactions. An object would hold onto its state and...encapsulation was the phrase, wasn't it? Like, we don't care what state it's storing, how it's storing it, providing it can do its job. Provided we can send a message to it to tell it do the next thing in the state or whatever. We don't work like that anymore. Do we not work like that anymore because we're not writing desktop applications in Smalltalk or Java Swing?

Nat Pryce: I think we work like that, but just in different places. And we sometimes don't admit to ourselves that we're working like that. So we work like that when we're composing microservices. So we're working like that at a larger scale. And maybe the idea...who was it, Alan Kay's idea that everything's an object and objects are smaller. You can take your computer and you divide it into smaller computers and smaller computers. One of each of these things is an object. At some point, maybe object orientation is not paying off with a fine grain. But at a microservice level, having a clear protocol that things communicate with and clear encapsulation boundaries and not letting other services reach into the database of a different service and just rummage about in it, couple yourselves to it, is a principle that people still apply. They might not use the same terminology, but they still apply it.

Duncan McGregor: Now we call that a bounded context. So what you're saying is that we used to have objects that sat in memory that didn't admit, didn't expose their representation. Now we have a bounded context that the whole machine or a whole set of microservices that are talking to a database that they don't expose.

Nat Pryce: Yes. It's similar design principles, right, but just at a larger scale. Where else? Oh, and if you look at, say, RX or Reactive Streams, that's a fantastic example of a really well-designed object oriented library or framework. I don't know what you'd call it. Library. And has a design pretty much the same as what we were trying to describe in GOOS, which is you've got state machines. You don't know what's in them. They talk through very clear, well-defined protocols. Those protocols let you create graphs in different structures that do different things. On top of that, you write some convenience code that then appears to be...that composes these objects and then acts as a very high-level declarative domain-specific language embedded in your 3GL. That's exactly how we write Reactive Streams code. We write what looks like pure functional code. Underneath it, there's lots of state machines ticking through and all of that stuff is going on. They all plug together through very clear interfaces that let you put them together into different structures to get different effects. So I think we still do it, right? But we like to describe it in terms of functional programming terms because it makes us sound that we understand maths.

Recommended talk: Is Software Engineering Still an Oxymoron? • Alan Kay • GOTO 2021

Changes in Software Development in the Last 15 Years

Duncan McGregor: I mean, I do feel that, to me, I still think of myself as an object-oriented programmer, but the thing that's changed is I don't think of sending messages to objects to change their state anymore. I send messages to objects to ask them about things and then I mutate them into other objects.

Nat Pryce: Transform them.

Duncan McGregor: Transform, yes. So this idea of objects encapsulating state is still there, but encapsulating state change, I don't think is.

Nat Pryce: Yes, apart from some areas of the system, right? I think that's where the object-orientation-everywhere idea, like, sort of didn't really work because there's parts of the system which calculate a result and there's parts of the system that coordinate activity or, you know... I read a blog post by someone who I can't remember at all who sort of described as there's parts of the system that are informatics and there's parts of the system that are cybernetic, right? The cybernetic systems, their job is to maintain homeostasis. It's like your server receives an event, right? It processes that result. Processing the result will calculate something that has to be sent back. There's your informatics bit, right? But then the server goes back to, like, hopefully, being able to receive the next request without having leaked any memory. So that's your homeostasis bit, right? And OO comes from a cybernetic sort of tradition and functional programming comes from a calculating results sort of informatics tradition. And our systems need both, right? And they need both sort of in different places of the system or in layers. And having just one way of doing things doesn't actually make building a real system easy. It can make it harder, right?

Duncan McGregor: Thinking back to the days of GOOS, 15 years now, what other changes do you see in the software development landscape?

Nat Pryce: Well, machines are a lot faster, right? And that changes how much you can test in one go, right? So there was like a very strict distinction that people were drawing between unit tests and, I don't know, people didn't have a good word for it, integration tests, not unit tests, right? Things that do IO, things that touch hardware, right? If you can run everything in memory, it goes fast. Debug is reliable. But mainly people are concerned about fast, right, fast feedback. And then as soon as you touch IO, it goes slowly. Well, that, you know, technology has changed. You can run a lot more, much faster now. We don't have spinning disks. We have, like, SSDs, you know, fantastic machines, I don't know, orders of magnitude faster, many orders of magnitude faster. So now we can run more in our tests at one go. And so there's less need to have lots of little unit tests to try and get that fast feedback.

But you know, if you use something like test containers to spin up a database, you're still going to have difficulty doing fault injection to sort of exercise your error-handling paths, for example. So there's still a need for that sort of abstraction level and the seams that let you instantiate and then test the pieces of functionality. But we can also do much more thorough testing of larger scales. That's one thing I've noticed.

I mean, functional programming, right? That's the other thing is like, you know, that...when we wrote GOOS, what? It was written in Java 6, I think, and didn't really have much support for functional programming in Java. But now since then, there is some support for functional programming in Java, but also modern languages, all modern languages now have much better support for that, like you say, transforming data rather than mutating data.

Duncan McGregor: Yes, I think it's the thing that we always could do. And I think the Java developers in our audience, should we still have one, will probably remember Guava maybe as the point where functional programming became convenient enough in Java that you could represent things as chains of calculations, composable chains, rather than it was just easier to mutate a list, you know, sort in place and so on, that sort of thing.

I like the idea that things are quicker. I'm not like...well, the machines are quicker. I do wonder whether we're squandering that a bit.

Nat Pryce: That's the software development tradition though, isn't it?

Duncan McGregor: Personally, I've sort of spent the last few weeks looking at how fast tests are to run in IntelliJ, and the answer is simply not at all. Like I would have...it takes 3 seconds to get feedback on practically anything these days. And as far as I can remember, it took 3 seconds to get feedback on the same amount of code 15 years ago.

Nat Pryce: One thing that's changed though, is, I've gone from Java to Kotlin as my main preferred language, the sort of enterprise delivery, whatever, we have a working type system, right? But that type system takes longer to do its type checking, but you can rely on it a lot more than you could in Java, which has complexities in its type system that make it rather inconvenient. And so people rely on Reflection and things like that in Java a lot more than they would need to in Kotlin.

You've got this trade-off with, like you say, with 3 seconds to get a result, but a lot of that might be type checking, and then we could move a lot of our checking into the type system, into a type-level modeling that we would otherwise have had to write unit tests for. So it's sort of paying off. And then you might not even notice the fact that I'm writing something, and now my ID is underlining stuff in red, and I'm just going to fix it. I've not even had to run a test. But in the past, I'd have had to run a test to find out that I've just made that mistake. So there's feedback that's faster in different ways, and definitely, that's changed how I think about designing things in a way that is, you know, different.

Duncan McGregor: Yes, I think we have learned to use the type systems we have and more sophisticated type systems to represent things about our software, haven't we? The whole making illegal states unrepresentable, I think, has changed the way we write software in the past 15 years. We could always have done it, but we didn't know that we could, and so we didn't.

Nat Pryce: Yes. Well, it's just too inconvenient. I mean, in Java with, like, use-site variance and things like that is just...sometimes it's just so painful to use and primitive versus reference types. Having to worry about that stuff, you just can't easily represent certain things. Too awkward. It'll get better, but Java is a slow-moving beast.

Duncan McGregor: Do you feel that we're writing software quicker than 15 years ago?

Nat Pryce: Not really, but we're also doing bigger things, I think. Maybe not justifiably, you know, we write where we would have written a server

... we now write 20 microservices, and now we have to worry about integrating an APM solution and instrumenting all of our HTTP calls so we know what's going on in our system, etc. You can say it's crazy, but at the same time, you think...at some point you've got to think, developers prefer to run a distributed system than use the modularization mechanisms in their existing languages, which means that those existing languages must be doing something wrong in the way that they do modules.

Duncan McGregor: Yes. I think the boundaries are always hard, and then we're in Conway's law, and the hard boundary supplied by microservice saves us having to go to somebody's desk and talk to them, maybe. I feel we have squandered a lot of the advantages that we've had over the past 15 years. Software is big in two dimensions, really, isn't it? It's big in its ability to scale out, how many requests per second we can handle, or how much data we can store, and then there's how many features we have, like what it actually does. I feel that we are able to store and access more data, and we're able to be more scalable, but I don't actually feel that we are delivering features any quicker these days.

Nat Pryce: We expect more from our features, right? That's the other thing. Back in the day, people would be quite, well, I wouldn't say happy, but they were put up with a desktop user interface created by a programmer in Swing or in .NET. Nowadays, they have people who can actually design user interfaces, explaining to the developers what a good-looking user interface and what a well-working user interface, let's say, actually should be like. I think we are expected to do more. We're expected to create websites that work on a wider variety of devices. It's not just a VGA screen. It has to work on mobile. It has to work on big desktops, iPads, a variety of operating systems, multiple different browsers, each with their own release cadences. That brings a lot of complexity that people just have to deal with. I was rightly joking about the microservices being sort of a crutch because language modularization systems aren't very good, but at the same time, we have to break our systems up because different parts of our systems have different scalability and failover needs. At that point, we were already running a distributed system, so we then repurpose it for modularization as well.

Duncan McGregor: I don't believe that, to be honest with you. I mean, pushing back, I think we tell ourselves that, but we can scale monoliths. We've had the same code base and different bits of it can scale in different directions. If Facebook can run a monolith, I'm sure that we can solve our problems with monoliths. The extent to which we break things up, I think it largely is fashion. And probably there are places where we should have queues and queue consumers, and maybe they should be different processes. But I think most of what we write should probably be sitting in one process that is then duplicated and load-balanced effectively. But moving things between having different microservices in order to have bounded context boundaries, yes, I don't believe in personally. Bring back the monolith.

Nat Pryce: All right. We've sort of gone off on a bit of a tangent there.

Duncan McGregor: One of the things I remember about those GOOS days, as you say, is that we were, in fact, developing interfaces for internal teams, largely, or simply for the desktop. And one of the places I feel that we really haven't managed to make agile work is with interaction designers. I feel that, in those days, we were able to be agile because we could sit with a customer, work out what they wanted the thing to look like as part of, "Are we going to do that this iteration?" Whereas interaction designers like things to be designed upfront. And that design upfront actually is the tail that wags the agile dog these days.

Nat Pryce: Yes. I can understand there's a lot of research that goes into it, especially if you've got a site that has to meet the needs of customers around the world. When you're just working for, I don't know, like a trading desk and you've got like four people that you're writing software for, what they want goes, right? But when you've got to be able to make your software usable by people who you never even meet, you rely very much on the research. But you're right. I mean, I've always struggled with being able to work incrementally and iteratively with designers, being able to say, "Okay, you know, I understand what the final design should be like, but we're coming in like this. So what's our first delivery and how can we get value, and then the next one, and the next one, and the next one? And how does the design evolve so that it remains usable as it's going through these intermediate states?" That's difficult.

Duncan McGregor: One of my biggest innovations recently has been to take the interaction designers final mock-ups of the thing and say, "Okay, this iteration, we are going to produce this with this scribbled out, this scribbled out, and this scribbled out. And then the next one, we'll undo some of the scribbling." Because finding a way to deliver value in the next week is, I guess, really back to what GOOS was about. The very first thing you should be doing is working out how to deliver the system. And then once you deliver the system, what is the smallest increment of value we can give our customers?

As you said about XP, it was how do we develop software that we need ourselves? If I'm writing software to format something for a book or total my bank account or whatever it is, the thing that I do is the smallest thing that will give me value. And if I need to write tests to think that I will be able to maintain that, I'll do that. If I don't need to write tests, you know, tests have to be an economic argument. They have to support this thing going on. Often I'll write them because otherwise if I come back to this later, I won't be able to do it. But that constant focus on, how can I give you value quicker whilst at the same time knowing that I'm going to be able to continue to give you value quickly for the next week and the next month and so on, that's the essence of XP, it's the essence of Agile, and I think the essence of what GOOS gave us, which was this guided by the tests. It was this outside-in thing, real focus on delivering to the customer, not doing anything that wasn't focused on delivering value to the customer.

Nat Pryce: Yes. I think you're saying, are we doing it as fast as we used to? Has it got faster? I don't think it has. But at the same time, I think part of it is, at the same time as Agile was happening, open source was happening. Agile and XP focused on continuous integration and then continuous delivery, then continuous deployment. And open source focused on sort of unsolicited changes, review, and that ended up with sort of the pull request. And those two things are coming from different cultures, different...I don't know if culture is the right word, but definitely different traditions with different constraints and different needs. But we have somehow sort of smashed them together where people in enterprise organizations are using pull requests in order to sort of elaborate in a way that's less effective than continuous integration was. And that's the sort of constant argument I see going on.

Duncan McGregor: It is amazing to me that trunk-based development didn't have to be a phrase 15 years ago.

Nat Pryce: Yes.

Duncan McGregor: Because what else was there?

Nat Pryce: It was just the way you did it. You had ClearCase, right, which had branching all over the place and merge requests. And then you had everyone else who didn't want to use ClearCase because it was so difficult and just did trunk-based development in Perforce and then Subversion and then whatever. And then now we're all reinventing ClearCase on top of something that doesn't need to be that complicated.

Duncan McGregor: Well, this has been two grumpy old men. I think maybe we should... This would be a good place to wrap it up before we get into a religious war. Thank you so much for your time today, Nat. If people want to find out more about you, where should they look?

Nat Pryce: I'm going to be at KotlinConf in May and Craft in May, end of May, June. So I'll be speaking there and running a workshop on the topic of...well, with you, we will be running a workshop on the topic of refactoring from OO to functional and looking at sort of how we do that in very, you know, how people build software in practice, as well as your sort of GOOS-style OO.

Duncan McGregor: In the context of this, probably characterize that as teaching us how to refactor from the OO style that GOOS championed to, I suppose, functional core imperative shell.

Nat Pryce: We'll be looking at like, you know, popular frameworks and sort of the way that they make heavy use of reflection and how we can introduce better typing and things like that.

Duncan McGregor: We'll arrange for details of that workshop, how to buy GOOS, and the book that we wrote together, "Java to Kotlin: A Refactoring Guidebook," to be in the show notes, along with a link to my YouTube channel, Pairing with Duncan McGregor. Thank you for watching.

Nat Pryce: Thank you.

Contributors

Nat Pryce

Nat Pryce

Co-Author of "Growing Object­-Oriented Software" (GOOS)