"Classic TDD or 'London School'?" - any opinions/comments/elaboration on Jason Gorman's post?

1705 views
Skip to first unread message

philip schwarz

unread,
Jan 8, 2011, 9:24:06 AM1/8/11
to Growing Object-Oriented Software

philip schwarz

unread,
Jan 8, 2011, 9:39:15 AM1/8/11
to Growing Object-Oriented Software
From InfoQ interview "Michael Feathers and Steve Freeman on Design"
http://www.infoq.com/interviews/feathers-freeman-design#

Feathers: It's interesting. For the people watching, the name of the
book is Growing Object Oriented Software Guided by Tests. It's
interesting that it's like a TDD book. There have been a number of TDD
books, but I think it's cool that it's the first one that really
carries out what I tend to look at as the London school of TDD, in a
sense. There was a bit of a different genesis in how people in the
London community back in the early 2000s approached TDD. That led us
some of the first insights going on, like the first paper you wrote
with Tim Mackinnon about mock objects. That was a cool thing, a lot of
stuff blossomed out of that, but I noticed as well that there has been
hard to convey what makes that approach different in a way.

Freeman: It's nice because we had a very strong community in London in
those days, in the early days. It was a very tight little group. It's
somewhere in the acknowledgments that we spent a lot of time arguing
about stuff, which tested the ideas. One of the things we really liked
as we were working our way through the book was that it comes out of
various experiences that we've all had. A number of us worked in
SmallTalk, which has a very - I think what Ralph Johnson called a
mystical view of objects - that there are these things and you send
messages to them. If you do that stuff inside, it's our emphasis and
it's very much about the messages between objects, rather than more
what's inside of them.

~~~~~~~~~~~~~~~~~~

Feathers: When working with teams, it's everybody likes to think that
object oriented design is this settled thing that everybody
understands, but it almost feels like often when we visit teams, they
have a bit of a top-down view design, in a sense. Particularly with C+
+ and Java, you can easily get into this point of view where these
things are just functions, it isn't just sending messages, there is
just like a function you might have in a functional procedure
programming language. It's funny, since some of the deeper stuff that
you get when you think about collaborations of objects and stuff like
that, for many teams it just never quite gets through.

Freeman: You pick whichever you want to belong to. One of our standard
diagrams is you got this graph of objects and they are all connected
up and - the objects are the circles and the lines are the connections
- what we do is we fade out the objects and concentrate on the
connections because for us not always, but in a lot of the code that
we write, that's the interesting bit. The languages we use make that
hard to seek because they concentrate much more on what's inside the
circle. The other sort of influence is certainly Nat a very strong
background in distributed systems and distributed objects and I have a
little bit of that. But again, you start to think in terms of
protocols, rather than individual message calls or individual methods
- how do this things talk to each other and what's the sort of
relationship between these calls? Within the circles, within the
blobs, which are the objects, they do whatever it is they do and this
is not a hard business. When you do that you find that it gives you
quite a nice flexibility in the code, because you can take this one
out and pluck another one in.

~~~~~~~~~~~~~~~~~~

Feathers: One thing I neat when I look at some of the designs that you
have in the book and some of the conversations we had over the years,
is that you really pushed what the pragmatic programmers call a "Tell
and don't ask" to a rather high degree. You send a message to an
object and in general you are not getting a return value back from it,
but you tell the object to do something for you and it does something
and it seems you end up with a decouple of design with that, don't
you?

Freeman: Yes. Some of that came from a challenge. There used to be an
architecture group in London and it turned into an Extreme Tuesday
club but I think it was Peter Marx or John Nolan who put this
challenge down that said "What happens if you wrote code with no
getters?" It's not necessarily something you actually want to do, but
it's a really useful exercise for forcing the way you think about code
and you can go quite a long way with that. The trick with a lot of
these exercises is to push them too far. Then, you can come back a bit
when you know where the edge is, but it's amazing, when you try a lot
of these techniques, just how far are the edges.

On Jan 8, 2:24 pm, philip schwarz

isaiah perumalla

unread,
Jan 8, 2011, 10:09:15 AM1/8/11
to growing-object-o...@googlegroups.com
These are my opinions, i think his example of the with EmailValidator ... is a bad example "using a mock Email Validator with the expectation that validateEmail() is called with the email addressed passed into openUserAccount() (which we know is duff) and that it will return "false", at which point we check what the controller does with a "false" response." this is not how mock objects are intended to be used, and i think he's missed a lot of important points.

I am not even sure if there is a london school TDD and classic TDD.
In my opinion GOOS builds on the many of ideas presented by Trygve Reenskaug (Working with objects), and Rebecca wrifs brock (Object Design), in her book she talks about designing role using CRC cards and simulating collaborations by getting people to play different roles passing a ball around to simulate messages. Mock are used in similar way expect you doing it programatically with the computer, but the key here is to listen to the feedback from the tests and refactor, re-design. 

The emphasis in GOOS approach is the designing high level messages between objects, which capture the domain model, i have not heard many people discuss this, which i think is the most interesting.
If anything, I would call this approach the classic OO design approach, mocks are just one of the tools used here.

Isaiah


On Sat, Jan 8, 2011 at 2:24 PM, philip schwarz <philip.joh...@googlemail.com> wrote:
here is the post: http://parlezuml.com/blog/?postid=987



--
Isaiah Perumalla

Steve Freeman

unread,
Jan 8, 2011, 10:22:16 AM1/8/11
to growing-object-o...@googlegroups.com
Looks like it's time for Nat to repeat his rant :)

The two "schools" of TDD are really addressing different aspects of a codebase, neither is sufficient on its own. For example, in the book we have a message translator that I think pretty much is driven by triangulation, even if the results are detected by expectations.

S.

Adewale Oshineye

unread,
Jan 8, 2011, 10:39:15 AM1/8/11
to growing-object-o...@googlegroups.com, growing-object-o...@googlegroups.com
Exactly. If there really were two schools then Jason could have used the same example to show the strengths and weaknesses of both schools.

Torbjörn Gyllebring

unread,
Jan 8, 2011, 11:24:36 AM1/8/11
to growing-object-o...@googlegroups.com
Actually Jasons conclusion and ending remarks in the post is:

"Our goal here is reliable code and good internal design, which means
that both schools of TDD are at times necessary - the Classic school
when we're focused on algorithms and the London school when we're
focused on interactions. Logic dictates that software of any
appreciable complexity cannot be either all algorithms or all
interactions (although, to be fair, I have actually seen applications
like these - and wish to never see such horrors ever again).

This is why my TDD training courses have one day of "Classic TDD" and
another day of "London school" TDD. It's not an either/or decision."

Sometimes it helps to actually read the post I guess :)

philip schwarz

unread,
Jan 8, 2011, 12:45:37 PM1/8/11
to Growing Object-Oriented Software
yes: I am simply interested in anything that people might have to say
about any of the content of Jason's post: its observations, its
conclusions, etc (except sausage-making). It is the first time I read
a blog post about different loci on which to focus when doing TDD
(1=interactions, 2=algorithms, others?), and the different techniques
used for each. I think most posts concentrate either on algorithms or
on interactions. e.g. the following recent ground-breaking posts by
Uncle Bob focus on algorithms:
"The Transformation Priority Premise"
http://cleancoder.posterous.com/the-transformation-priority-premise
and
"Transformation Priority and Sorting"
http://thecleancoder.blogspot.com/2011/01/transformation-priority-and-sorting.html

On Jan 8, 4:24 pm, Torbjörn Gyllebring <torbjorn.gyllebr...@gmail.com>
wrote:
> Actually Jasons conclusion and ending remarks in the post is:
>
> "Our goal here is reliable code and good internal design, which means
> that both schools of TDD are at times necessary - the Classic school
> when we're focused on algorithms and the London school when we're
> focused on interactions. Logic dictates that software of any
> appreciable complexity cannot be either all algorithms or all
> interactions (although, to be fair, I have actually seen applications
> like these - and wish to never see such horrors ever again).
>
> This is why my TDD training courses have one day of "Classic TDD" and
> another day of "London school" TDD. It's not an either/or decision."
>
> Sometimes it helps to actually read the post I guess :)
>

Adewale Oshineye

unread,
Jan 8, 2011, 6:29:44 PM1/8/11
to growing-object-o...@googlegroups.com
On 8 January 2011 16:24, Torbjörn Gyllebring

<torbjorn....@gmail.com> wrote:
> Actually Jasons conclusion and ending remarks in the post is:
>
> "Our goal here is reliable code and good internal design, which means
> that both schools of TDD are at times necessary - the Classic school
> when we're focused on algorithms and the London school when we're
> focused on interactions. Logic dictates that software of any
> appreciable complexity cannot be either all algorithms or all
> interactions (although, to be fair, I have actually seen applications
> like these - and wish to never see such horrors ever again).
>
> This is why my TDD training courses have one day of "Classic TDD" and
> another day of "London school" TDD. It's not an either/or decision."
>
> Sometimes it helps to actually read the post I guess :)
I read Jason's post. I suppose I was unclear. My point is that I don't
believe there are 2 schools of TDD any more than hammers and
screwdrivers represent different schools. It's a false dichotomy and
whilst Jason comes to that conclusion at the end he still says that
the schools exist even though you should be a member of both.

Uberto Barbini

unread,
Jan 10, 2011, 5:42:02 AM1/10/11
to growing-object-o...@googlegroups.com
>> This is why my TDD training courses have one day of "Classic TDD" and
>> another day of "London school" TDD. It's not an either/or decision."
>>
>> Sometimes it helps to actually read the post I guess :)
> I read Jason's post. I suppose I was unclear. My point is that I don't
> believe there are 2 schools of TDD any more than hammers and
> screwdrivers represent different schools. It's a false dichotomy and
> whilst Jason comes to that conclusion at the end he still says that
> the schools exist even though you should be a member of both.
>

I agree with you. What he calls "London School" is more "TDD used to
model your domain" and "classic TDD" is more "TDD used to solve
algorithm".
Still I read the article several times but I didn't get the email
validator example.
First there are regex to validate email addresses.
Second without any code it's difficult to understand for me how he
though London School would have solve it without triangulation.


cheers

Uberto

Nat Pryce

unread,
Jan 16, 2011, 1:43:08 PM1/16/11
to growing-object-o...@googlegroups.com
On 8 January 2011 14:24, philip schwarz

That's a very entertaining, well-written piece and I bet it's a good
way of drumming up customers for his training course, but
unfortunately is full of factual and logical errors. I don't know why
he wrote what he did, since Jason has known us for years and we've
frequently spoken at XTC and many conferences.

His "history" of where his "London School" of TDD comes from is
incorrect -- it didn't come from banking projects in the City of
London. The mock objects technique was invented by the guys at
Connextra who were writing a contextual advertising system for the
web. I learned of it at XTC and applied it to the Ruby back-end of a
(what would now be called) AJAX mobile web-app I was writing to
display F1 race results on hand-held computers at race-tracks. I
ported my Ruby code to Java to support my development of an F1 race
strategy simulation, and shared the code with the folks at Connextra
-- Tim McKinnon and Steve in particular -- and we extended it and
eventually open-sourced it. That evolved into jMock as more and more
people asked for features. The emphasis on driving from acceptance
tests and functioinal tests we picked up from the XP white book,
emphasised by our own experience of the limitations of unit-test-only
TDD.

By picking two different examples he's actually *not* showing the
difference between his two Schools. How does his "Classic School" of
TDD address the kind of larger-scale integration concerns he talks
about in his "London School" example? He doesn't actually say.

The Roman number example is a small, pure function and, as we say in
GOOS (despite it apparently being the key text of his other school of
TDD), naturally lends itself to being tested by making assertions on
results.

The distinction he seems really to be drawing is not between
"algorithms" and "interaction". It's between pure functional (and
maybe procedural) and event-driven. There is, after all, an entire
field of study of distributed algorithms that are entirely event
driven.

The idea that using mock objects does not mean you do test
triangulation is also nonsense. But his example doesn't even support
that statement. The test of the sign-up controller would use a mock
object and would (it seems -- it's hard to tell without code) entirely
cover it's behaviour. The problem he describes with the "London
School", where it does not perform the triangulation that comes from
his "Classic School" approach, is in the test of the EmailValidator.
This object takes an email address and returns true or false to
indicate its validity. That's a *pure* function -- the does not
involve mocking and would be tested with asserts, following in the
style of his Classic School. So his example actually illustrates a
problem with the way he has applied "Classic School" TDD! Assuming by
"London School" he means GOOS, we certainly do not suggest skimping on
unit-testing individual classes so that their behaviour is not
adequately tested!

(However, some of is "duff" email addresses are actually perfectly
correct -- test triangulation won't help you if you don't actually
know the domain!)

Again, I see the problem with this article to be a focus on finely
detailed TDD *processes* that are to be blindly followed. His
conclusion is reasonable -- as long as you believe that the choice is
between following one detailed process vs. another.

In my opinion it's better to focus on the benefits of different design
styles in different contexts (there are usually many in the same
system) and what that implies for modularisation and inter-module
interfaces. Different design styles have different techniques that are
most applicable for test-driving code written in those styles, and
there are different tools that help you with those techniques. Those
tools should give useful feedback about the external and *internal*
quality of the system so that programmers can "listen to the tests".
That's what we -- with the help of many vocal users over many years
-- designed jMock to do for "Tell, Don't Ask" object-oriented design.

--Nat

--
http://www.natpryce.com

Adewale Oshineye

unread,
Jan 16, 2011, 6:01:07 PM1/16/11
to growing-object-o...@googlegroups.com
This really ought to be a blog post.

Philip Schwarz

unread,
Jan 16, 2011, 6:57:37 PM1/16/11
to growing-object-o...@googlegroups.com
thanks, glad that I asked for input on the post.

On 16 January 2011 18:43, Nat Pryce <nat....@gmail.com> wrote:

Matt Wynne

unread,
Jan 17, 2011, 2:47:56 AM1/17/11
to growing-object-o...@googlegroups.com

On 16 Jan 2011, at 23:01, Adewale Oshineye wrote:

> On 16 January 2011 18:43, Nat Pryce <nat....@gmail.com> wrote:

>> That's a very entertaining, well-written piece and I bet ...


> This really ought to be a blog post.

+1

cheers,
Matt

ma...@mattwynne.net
07974 430184

philip schwarz

unread,
Jan 22, 2011, 4:46:40 PM1/22/11
to Growing Object-Oriented Software
Today Jason posted this screencast on "Classic TDD vs. London School":
http://parlezuml.com/blog/?postid=994

On Jan 8, 2:24 pm, philip schwarz
<philip.johann.schw...@googlemail.com> wrote:

Uberto Barbini

unread,
Jan 23, 2011, 6:11:29 AM1/23/11
to growing-object-o...@googlegroups.com
Maybe I'm dense but I cannot see any real difference between GOOS and
what Kent Beck, Michael Feathers and Ward Cunningham are writing (both
as code and books) since years.

JMock is a nice library to do what KB preaches on mocking in
"Implementation Patterns"... still I wouldn't call it a "school" for
that.

I also consider GOOS the book that is offering the best whole view of
software development. Other books are more about on specific
techniques.
So I think there is a "TDD done right school" and a "misunderstood TDD
school". But the first is not London specific... ;)


cheers

Uberto

Steve Freeman

unread,
Jan 23, 2011, 6:22:04 AM1/23/11
to growing-object-o...@googlegroups.com
Actually, there are some differences between us and Kent. From what I remember of implementation patterns, in his tradition, the emphasis is on the classes. Interfaces are secondary to make things a little more flexible (hence the 'I' prefix). In our world, the interface is what matters and classes are somewhere to put the implementation.

Like any technique, there is a huge "misunderstood" school. The "London" tag is an accident of history, but we did have a strong local group at the time that led to a number of innovations.

S.

Philip Schwarz

unread,
Jan 23, 2011, 8:49:55 AM1/23/11
to growing-object-o...@googlegroups.com
Hi Uberto,

you said:JMock is a nice library to do what KB preaches on mocking in "Implementation Patterns"

There are no occurrences in the book of either 'mock' or 'stub'; can you point me to the pages/chapters in question?

Philip

Aviv Ben-Yosef

unread,
Jan 23, 2011, 9:15:44 AM1/23/11
to growing-object-o...@googlegroups.com
In the video, Jason shows interfaces called Boxoffice, Performance, Seat and implementation classes BoxofficeImpl etc.
This is frowned upon in GOOS, but in cases like above, I usually can't find any real better name to give the implementation classes. What would you do in this case?


On Sat, Jan 8, 2011 at 16:24, philip schwarz <philip.joh...@googlemail.com> wrote:
here is the post: http://parlezuml.com/blog/?postid=987



--
Aviv Ben-Yosef
Miracle Max: You rush a miracle man, you get rotten miracles.

David Peterson

unread,
Jan 23, 2011, 9:22:10 AM1/23/11
to growing-object-o...@googlegroups.com
I've not watched the video, but my off-the-top-of-the-head suggestion would be to call the *class* BoxOffice and have it implement interfaces representing the roles that it has, e.g. TicketSeller.

David
---

philip schwarz

unread,
Jan 23, 2011, 9:55:33 AM1/23/11
to Growing Object-Oriented Software
I like your suggestion, it follows the advice we find in the last
paragraph of GOOS section 'Impl Classes are Meaningless":

########################################################

Sometimes we see code with classes named by adding “Impl” to the
single interface they implement. This is better than leaving the class
name unchanged and prefixing an “I” to the interface, but not by much.
A name like BookingImpl is duplication; it says exactly the same as
implements Booking, which is a “code smell.” We would not be happy
with such obvious duplication elsewhere in our code, so we ought to
refactor it away.

It might just be a naming problem. There’s always something specific
about an implementation that can be included in the class name: it
might use a bounded collection, communicate over HTTP, use a database
for persistence, and so on. A bridging class is even easier to name,
since it will belong in one domain but implement interfaces in
another.

If there really isn’t a good implementation name, it might mean that
the interface is poorly named or designed. Perhaps it’s unfocused
because it has too many responsibilities; or it’s named after its
implementation rather than its role in the client; or it’s a value,
not an object—this discrepancy sometimes turns up when writing unit
tests, see “Don’t Mock Values”.

On Jan 23, 2:22 pm, David Peterson <da...@crowdsoft.com> wrote:
> I've not watched the video, but my off-the-top-of-the-head suggestion would
> be to call the *class* BoxOffice and have it implement interfaces
> representing the roles that it has, e.g. TicketSeller.
>
> David
> ---http://blog.davidpeterson.co.uk

Uberto Barbini

unread,
Jan 23, 2011, 10:29:16 AM1/23/11
to growing-object-o...@googlegroups.com
I rechecked and it was on "Test-Driven Development", page 144-5.

cheers
Uberto

philip schwarz

unread,
Jan 23, 2011, 10:38:26 AM1/23/11
to Growing Object-Oriented Software
ok, thanks

Uberto Barbini

unread,
Jan 23, 2011, 10:49:30 AM1/23/11
to growing-object-o...@googlegroups.com
On Sun, Jan 23, 2011 at 12:22 PM, Steve Freeman <st...@m3p.co.uk> wrote:
> Actually, there are some differences between us and Kent. From what I remember of implementation patterns, in his tradition, the emphasis is on the classes. Interfaces are secondary to make things a little more flexible (hence the 'I' prefix). In our world, the interface is what matters and classes are somewhere to put the implementation.
>
> Like any technique, there is a huge "misunderstood" school. The "London" tag is an accident of history, but we did have a strong local group at the time that led to a number of innovations.

Of course you're much more qualified of me on this. ;)

But what I wanted to say is that (IMHO of course) the "GOOS way" is
not a different technique from "traditional TDD", rather a kind of
evolution. So presenting them as opposite schools on how to do TDD is
off the mark.
I had a discussion on this with a coworker so I rechecked on some
other books I have on OO design and TDD (TestDriven Develoment,
Implementation Patterns, Refactoring to Patterns, Working Efficiently
with Legacy Code, Clean Code).
At the end, my conclusion was that GOOS contains several innovations,
but it's on the same "stream". But as I said, maybe I'm too dense to
spot the differences.

Specifically on interfaces, my old position was to avoid any interface
with just one implementation. After reading GOOS I've started to use
them more freely but still a bit pedantic to write both interface and
class when I cannot find different meaningful names for each of them.
GOOS examples are very clear, still when writing our own software it's
harder... ;)

cheers

Uberto

J. B. Rainsberger

unread,
Jan 24, 2011, 2:02:47 PM1/24/11
to growing-object-o...@googlegroups.com
Aviv Ben-Yosef wrote:

> In the video, Jason shows interfaces called Boxoffice, Performance, Seat
> and implementation classes BoxofficeImpl etc.
> This is frowned upon in GOOS, but in cases like above, I usually can't
> find any real better name to give the implementation classes. What would
> you do in this case?

Quick answer: try a Structural name of the form
"HowIImplementItInterfaceName"

Examples: JmsBasedPostOffice, HibernateBasedCustomerRepository,
AxisBasedStockQuoteService

Deeper answer:

If you can't see what about an implement makes it different from the
underlying interface, then the interface might belong elsewhere. Try
moving up one level of abstraction.
--
J. B. Rainsberger :: http://www.jbrains.ca ::
http://www.thecodewhisperer.com

Nat Pryce

unread,
Jan 24, 2011, 6:13:26 PM1/24/11
to growing-object-o...@googlegroups.com
On 8 January 2011 14:24, philip schwarz

Thinking some more about this, I think the line that really bothers me
is "we move on to the next easiest failing test."

Maybe it's a poor choice of words but, taken at face value, I think it
illustrates a deep misunderstanding of TDD.

Firstly, TDD is not about writing a bunch of failing tests that we
make pass one at a time. TDD stipulates that we write one test at a
time, implement just enough to make it pass, make the implementation
as simple as possible (note: simple, not easy), and continue by
writing another test.

Secondly. we don't order tests by what is easy. We test what we need
to do next and we MAKE that easy to test. Making it easy to test might
actually be difficult to do: it might bring to light a shortcoming in
our design and force us to address it.

That, to me, is the essence of the TDD process: the experience of
writing a test gives us feedback about the quality of our design. And
I want that that feedback is to be met head on, not avoided by always
taking the easy route.

--Nat

--
http://www.natpryce.com

Mauricio Aniche

unread,
Jan 24, 2011, 8:53:32 PM1/24/11
to growing-object-o...@googlegroups.com
Hi,

i was trying to reply in his video, but it seems that youtube
does not accept big texts! So I am gonna put it here! :)

--
I guess the "London school" is the natural way when you develop a
really object-oriented code. When your code grows, you start breaking
up responsibilities in different classes. So, as we have dependencies
between objects, we need to mock them in order to test the behavior of
that unit.

I don't get when you say that "classic school" is focused on
algorithms. Even using "classic school", when you are testing a system
that grew up to a big OO system, you will test the relation between
dependencies and you would end up using mock objects the same way.

As I have read both books, the main difference for me is that, GOOS
are focused on objects and their relationships since from the
beginning. It tries to solve problems, but always thinking on objects.
That doesn't happen in Beck's book, which is more focused on sorting
the problem out in the simplest way, with less possible code, one step
at a time.
--

Also, in the last e-mail, Nat talked about simple, not easy. I blogged
about it in my brazilian portuguese blog, but I translated it to
english a couple weeks ago. In this post I talk about that "simple
changes may not lead you to simple solutions":
http://blog.caelumobjects.com/2011/01/10/simple-changes-might-not-lead-to-simple-solutions/
. Any opinions would be appreciated.

Regards,
Mauricio Aniche

Reply all
Reply to author
Forward
0 new messages