let's do this and I'm just going to make
sure oh the mic still works all the way
back here pretty good great I'm not
going to do the recording in uh good
morning thanks everyone for being with
me here at 9:00 LOL um so this is a talk
about coping with the existential dread
you get when everything kind of
sucks right that's that's the opening
Gambit we're going to go on a an emot
roller coaster about how you feel when
everything kind of sucks because we've
all been there and we've all opened up a
code base and you know that like
horrible sigh of like oh my God what is
this that washes over you when you open
something that maybe hasn't been touched
in years by someone who didn't care who
did something very very quickly under
very very tight time constraints and
you're left trying to pick up the
pieces um
so yeah this is about kind of finding
hopeful nihilism and optimism in a place
where things can often be painful and
uncomfortable sounds like we're going to
start a
concert so my name's David and I spend
way too much time thinking about
software design this is basically my
toxic character trait so I'm the head of
architecture for a company in London
called New Day we're a credit card
company not a life coaching company
despite the name um we're hiring what
ever but really um I'm here to talk to
you about what why design is important
and everything you do and why literally
everything in the world matters right so
the you know the truth is I'm a
programmer and you will pry my keyboard
out my cold dead hands that said there's
not a lot of code in this talk so if you
think you're going to see demos you're
going to be a bit disappointed what
we're going to do is talk about how
software makes us feel and how we can
take those feelings we have about
software design and turn them into kind
of actionable things that we can do to
make our code bases
better so I did this small kind of viral
tweet at the end of last year when I was
trying to fix up this like objectively
terrible codebase and I looked at this
thing and I had that sinking horrible
feeling of dread that I was describing a
moment ago and I did what I always do
when I see something awful I open
Twitter and I rage tweet into the void
right so I remember just thinking this
is a damning indictment on the state of
software design in like 2022 2023 where
people can do this and think that this
is design right it's it's horrendous and
mostly Twitter agreed and it was it was
good and I got to feel Vindicated in
being angry at a thing um basically
because organizing your code by
architectural feature is like basically
a hate crime it's a hate crime that you
can commit against your software and my
inner monologue was just sitting there
screaming why is this like this what
does this even do it doesn't make any
sense so I'm hopefully going to try and
explain why it is like this and how we
can make it make sense because the truth
is that organizational pattern is like
taking your classic car collection
getting your hammer out and smashing it
up and organizing it by Wheels steering
wheels seats windshields Bonnets and
Boots doesn't make any sense you remove
all context from a thing when you break
it up into small
parts now so much of the talk that
you'll hear about design in in software
always ends up getting dragged all the
way back to work on in the 1990s about
design pans and this isn't a talk about
design patterns so don't worry you don't
have to get up and walk out um but I
want to pay them a little bit of lip
service so we actually understand what
design patterns are before we talk about
the thing that isn't design patterns
because it might be easy to misinterpret
this talk of some kind of tyde against
design patterns and it's really not it's
not a rallying cry against standards or
anything like that so most people
actually where design patterns come from
it's a little bit of an interesting
story so design patterns originated in
the works of a man called Christopher
Alexandra who was like a real life
architect he built buildings right none
of the fake architecture job titles like
I have um and he wrote this amazing book
in the
1970s
1960s called it's brilliant notes on the
synthesis of form which is definitely
like my progressive metal album title I
think at this point and um and basically
a bunch of computer scientists in the
70s and ' 80s wrote uh read notes on the
synthesis of form and they started
metabolizing the ideas and it led to the
design patterns movement and they
started writing books around how design
patterns from architecture could be
applied to computer programming
languages so the gang of four book here
which came out in
1994 is proberly kind of the
foundational text around design patterns
and what it did is it attempted to lay
out a series of structural creational
and behavioral patterns um that were
common in software of the time there are
a bunch of other noteworthy books that
followed around this kind of patent
language thing from people like Kent
Beck who wrote Small Talk best practices
Martin Fowler who wrote the very very
famous and very very wordy patterns of
Enterprise architecture blood blood blur
some subtitle very very good book um but
ultimately the intention of all these
books was good and it targeted only one
thing and this is the thing that people
often misinterpret to provide concrete
guidance around descriptions of common
solutions to Common problems that they
had seen in software at the time right
hey we looked around all the work we did
and this is the thing that was happening
over and over again it wasn't hey we sat
in a room and we designed this pattern
and we think you should fit this to all
of your software right very very
different intent so what design patterns
really are is giving names to model
answers to model questions right and you
know the really really powerful thing
about language and actually Eli's
keynote yesterday really touched on this
is you give Concepts names then we can
talk about them so design patterns were
really really important in leveling up
the way we spoke about the things that
we observed in
software now this isn't a talk about any
of that because patterns try and make
sense of categories of things that are
all the same and actually I want to talk
about all the things that are different
in your
software now I suppose I kind of just
lament that all of the talk of design
patterns and software really devolves
down into this kind of talk of design
patterns because they're the least
interesting part like if there's a model
answer you don't have to think about it
right that's that's not very interesting
they're about all the parts of your
system that are familiar so with the
acceptance of that what we actually did
over the years since kind of the 70s and
' 80s we is we pushed our programming
languages to innovate to make a lot of
those patterns obsolete over time and
that's quite interesting because once we
did that it kind of feels like we forgot
to talk about anything that didn't fit
into these welln notated patterns and
you know the truth is that where real
design starts where where the talk of
patterns end and you're just trying to
find form for all of the other stuff in
your system and that's kind of the root
of why people always use the joke that
naming is hard because you're trying to
find form and structure for all the
other stuff that doesn't fit into any of
the neat
boxes now on the other end of the
spectrum we have kind of large scale
organizational patterns things like you
end tier hexagonal architectures 12
Factor apps and all of those movements
are all about trying to De describe
characteristics and prescriptive form
for an application arrange your things
like this and it will make sense have
these characteristics in your
application and it will make sense but I
think software design kind of has more
axes than just functional patterns and
large scale architectures right one or
the other and I think the most
interesting stuff is the stuff that
falls in the cracks in between because
that's the moment to moment Line to Line
way that most programmers interact with
their
code so here's a here's a horrible deep
confession and it might not be a
surprise to anyone from the look at me
that back in time I was a pure Arts
student Way Way Back In Time right like
and I literally studied literature and
philosophy and politics and history and
then the computer science
degree why would you do that I always
wanted to be a programmer that's the
truth I always wanted to be a programmer
I thought there was this kind of um
ineffable magic about what we do about
making things that's so cool
right and I never never lost that
addiction from the first time I saw
something that I did change on the
screen but for the first half of my
career I really really struggled to
reconcile the aesthetic sensibilities of
design you know I started programming in
the mid
1990s there were no websites there were
just a few books um and these books
right these really scientific textbook
style formal language design paty books
these two things just didn't match in my
head because I got into programming
because I wanted to make games like
every 10-year-old does right that's the
truth
so I kind of I went to University and I
was I was feeling a little bit
disillusioned in my first year and I
stumbled across you know Donald nth
right anyone else done a computer
science degree in here no computer
science degrees one person anyone heard
of the art of computer programming the
book right so the interesting thing so
Donald Donald nth wrote this book called
um literate programming way back in
1984 um which is literally the year I
was born so there are no new ideas so
nth had this idea of programming being
um a thing that should be formed of a
documentation language and a programming
language and you're like what okay so I
continued reading and he was really
focused on the idea of comprehensible
code and you know he he he really he
wrote this this whole book called
literate programming and this is really
consistent with Donald nth so Donald nth
is the man that's been working on the
art of computer programming since the
70s I think maybe 60s who took 10 years
out to build text the formatting
language so he could write the book
about computer programming for which he
made up a fake microprocessor
architecture and a fake programming
language so he could teach what computer
programming was meant to be from the
purest possible philosophical position
it's like cool cool I mean I I respect
the hustle it's just a bit of a slow
Hustle but like this this book that he
wrote about literate programming I
thought was really really awesome and it
just
it stuck with me because it was really
really focused on this idea that
programming languages and documentation
languages were this symbiotic thing that
gave context a
code now if you think about it when he
started writing this book in the 70s all
the programming languages at the time
were far lower level than languages we
use today I was going to say sucked but
they didn't really suck they were just
very primitive they were very close to
the
metal and actually modern programming
languages over time have dragged
themselves both to high order
abstractions and to be more like the
written word year by year by year and we
we keep on going right and actually I
was reading this and thinking Donald nth
was right in that programming languages
are kind of now this amalgam of
documentation and implementation
language that we smush together like
most programing languages didn't support
the concept of comments in the 70s as a
as an example so programming languages
have kind of trended towards being more
literate over time but this idea that
software should looked at through the
lens of literature really really really
stuck with me because it is the same and
it was kind of a little bit of a
revelation like a light bulb moment for
baby programmer art student David who
had spent time studying English
literature like oh God this is a
text of course it is you know it changed
the way I started writing code but just
like literature software only becomes
good if you focus on its form as well as
its
function light bulb moment so over the
years I've come to this really precise
definition of what I believe software
really is I believe software is a
constrained form of communication
between programmer and programmer that
describes Concepts and problems that
just so happens to be executed by
machines by accident it's almost like a
happy side effect that we managed to do
this what we're really doing is we're
describing a problem space in a
constrained language that's really like
good writing and the more you think
about it the more it starts to click you
spend so much longer of a larger portion
of your working day reading code than
you do write it your code exists in a
context it has subtext it has authorial
intent sometimes it has unreliable
narrators when the intent of the author
isn't manifested and you end up with
bugs all these idioms we used for
literature can be applied to software
your code your code has form it has flow
it has a rhythm just like any other
writing but most importantly your code
has reason it has intent it has a
purpose for
being
so this
um everyone talks about clean code but
like this has nothing to do with clean
code really you know the the problem
with that book is the first three
chapters are just the sentence name
variables well over about 5,000 words um
it's a really God awful obviously
terrible book that's cast this horrible
long Shadow over software and reduced
all disc discussions of design to like
oh have you got your variables named
right have you split things up into
small functions it's just it's really
dogmatic it doesn't actually help
anybody and the the back half of it is
all complete garbage and was from the
day it was published about dead Java
Frameworks I just burn it honestly now I
always say this and everyone you know
everyone's like oh my God heresy how can
you say that about clean code that was
the most important book at me too right
me too and and actually at one point in
my career I thought rules about basic
hygiene were the same as design but
they're not right I I've come to Value
this idea of intentionality over any
concept of kind of cleanliness and
syntactic conciseness I guess um you
know I someone asked me a question when
I've done this talk previously like oh
but you know clean code has its place in
time and I think that's true you know I
think 15 years ago when that book came
out there was very very little in the
space that even tried to approach some
of these topics and there's a little bit
of of gratitude we have for someone kind
of introducing these Concepts into that
conversation but I just think it's aged
very very badly so when I talk about
intentionality let me let me tell you
what I really mean um it means every
Character Matters literally every single
thing you type you have to type for a
reason and everything matters just like
in writing and when I when I think about
software I want to approach the work as
if it matters the Whit space matters the
Rhythm in the code matters the form the
naming the function they're all
important right code written with that
kind of thoughtfulness and
intentionality and respect for the
reader is what matters to me I think
that's what makes software good and
we're going to go into detail don't
worry not just in the
abstract so the interesting thing is
when you stop thinking of your coders
literature you start valuing different
ways of communicating in code than you
did before
now we can communicate on the macro
scale with kind of large scale
organizational patterns so the the the
classic example that lots of people have
used before is NBC anyone made an NBC
application before right everybody were
they all
websites yeah yeah every single one of
them so the interesting thing about MBC
is it's an organizational pattern that
obscures the intent of your code
completely if I open a code base that is
an MVC website all I see is cool you
built a website there's nothing about
the structure or the form or the flow of
that codebase actually tells you what
the website does or what it's about
there's nothing present in that
organizational pattern but it so neatly
maps to the idiom of web development
that actually it's kind of okay right
like it it works well in that context
but it's constrained it's compromised um
so I actually find the micro scale again
more interesting where the the way that
you form specific pieces of code on a
function to function module by module
way telegraph's intent
because form and flow are the tools we
have to increase cohesion in a code base
let me use an example here to illustrate
this so when I say use form and flow and
cohesion I want you to take a look at
this screenshot first and we're going to
look at a second one now you don't need
to understand every line of code here
it's basically a nonsense it's a nothing
right there's some HTTP stuff and some
error response no checking right
whatever but it's difficult to read
because there is no form and there is no
flow and there is no organization in
that function at all what it does is it
forces you as the programmer to
comprehend every line statement by
statement and build up a mental model in
your head where your head Computing
what's
happening so we use paragraphs in the
English language to group related
Concepts so code is the same this is
using form and flow in a piece of code
lines mean something they carry me
meaning if you use them everywhere or
nowhere you're removing like an entire
category of expression weird so this
incred this is like a really really
incredibly small scale example to
illustrate the difference and you know
it makes me think that you know good
form in good code like it reads like
it's a rhythm it's like poetry you're
telling a reader I do this and this and
this and I breathe and I pause and now I
do this and I breathe and I pause and I
do this and I breathe and I pause it's
diction um so it's it's what happens
when an aesthetic sensibility matches
the intent of the content of the work
and all I really did was delete a few
lines of code like I deleted a few empty
lines to make it easier to comprehend
and you know form and flow then becomes
something you use to communicate intent
you're directing the
reader and you know the truth is things
like this are often lost in the morass
of kind of linters and things like that
like languages that rely on linters over
static analysis hello JavaScript often
butcher a category of expression in the
code because they're dictatorial about
form the same goes if if we got any go
programmers in the room no thing about
go as a as a language is it's got very
very strict rules around form so every
go program you look at looks the same
same with closure every closure program
looks like a a lot of brackets and
nesting and you have to really really
read and comprehend everything in your
head to grab the intent of
piece so form is important because it's
design now the more you st thinking
about software through this lens of kind
of form and flow and literature and more
importantly design it became apparent
that I was really trying to I was I was
reacting to the inherent complexity in a
lot of modern software development
really and and that is actually a design
problem more than anything
so I've been working on a sentence
recently that's what I do now I don't
write software write
sentences this is the real thing that
makes me mad in all of software in the
world I believe so the complexity of
your application should be at most as
complex as the problem space it inhabits
and no greater and the amount
of software that fails that sniff test
is
remarkable right they they they lose
themselves under infrastructure and 300
Bill pipelines and guilt uh and get subm
modules and like a thousand different
categories of test Suites and it's just
like where the is the software
in the middle of all of this absolute
chaff like it feels sometimes like
trying to find a needle in the Hast
stack right and it's a shame right like
and because all those things are these
kind of grand designs about an eventual
destination and quality and focus and
they're all people try to do good things
but losing the message on the
way and
actually focusing on the correct form to
express the problem space they have now
and the scale of the problems they have
now much more valuable to that piece of
software than all the stuff around it
like it makes working in systems like
that kind of like swimming through treal
it's almost like since the
popularization of microservice
architectures we forgot how to build
nice small things you know and nice
small things are beautiful I think the
best software we have is kind of the
antithesis of that statement it's
software that is smaller more beautiful
and concise that contains a larger
problem space than you think it could
possibly manage right that's that's
beautiful
design now the interesting thing about
kind of software design is that even the
use of the word design here is probably
contentious because I I appreciate that
a lot of programmers don't perceive
themselves to be visual people right
it's a it's a Trope it's not true but
it's a Trope so
designs as a exists specifically to
solve problems and communicate intent
using Form and Function that's what
design is people often confuse design
with art art is the thing we use to
express ourselves to cope with The Human
Condition there are commonalities
between those two things but they are
not the same right so let's we we're not
thinking about art we're not thinking
about making things pretty we're
thinking about design and
communication so the interesting thing
about design is it's really temporal in
nature well those are really blown out
color petts on those slides so these are
two really really iconic pieces and I do
not believe I'm about to say this of
period design
we're all old um and the interesting
thing about this is they're both
nonsense now but those designs don't
mean anything to people that were not
there at the time and didn't use them
precisely because designs are temporal
and exist in a
context right and and same with software
right so there's there this really
interesting observation actually these
two iconic designs weren't really the L
of their lines at all and people look at
them and think they're obsolute delete
things but actually they both evolved
and
changed now that's because fundamental
to the concept of design is the concept
of
iteration phones didn't cease to exist
Walkman didn't cease to exist they both
were iterated out to touch phones and
mobile phones and dism and iPods and the
really like irony irony maybe
fascinating artifact of these two
designs is they converged two completely
disperate things converged because we
realized the real problem we were trying
to solve was the trans of audio and not
making phone calls or listening to you
know banging lead Zeppelin albums or
something like there were different
things and they converged and I think
this is really inherent this
evolutionary process that underpins
great design and and the nice thing
about that is it really exactly is the
same reason that some of the disciplines
we have in software development that are
fundamentally of software like tdd
getting Caster's design totally makes
sense right the the reason tddd makes
sense as design is it's fundamentally an
iterative process that involves you
building context over time super super
fascinating right and you know I know
there's a trend at the moment of people
to kind of criticize tdd and its utility
on the internet but I can tell you one
thing for certain any of the people that
post big screeds about tdd being wrong
have never used it for iterative design
I'll tell you exactly what they did they
wrote A test they made it past and they
moved on cool first two steps of a
three-step process gold star right most
of the people that criticize tdd haven't
really used it to realize design right
they just they never really did it they
didn't do the refact they didn't do the
cycle and it also kind of highlights
this other magical quality of design as
a discipline that aot this kind of
thinking about the form of things lead
you to which is like there are entire
categories of problems that exist in the
world that are completely invisible to
you until you can observe them visually
it's like a it's a funny Quirk and again
this trips up a lot of people that don't
think that themselves as visual people
but we've all had the experience of
opening up a software library and kind
of you know C your you're intell sensing
your way through life and he just like
why are the apis structured like this
this is like this is horrible right
that's you having a vicious response to
the design of their API and that's
precisely what a pattern like tdd in its
red green refactor red green refactor is
meant to put front and center in the in
the code editor of the author as they're
writing it right there's this really
great um anecdote about when they were
first filming Star Wars and it was one
of the Star Wars sequels and you know
how like all the Star Wars films after
the'80s sucked and it's because the
scripts were very bad right funny story
George Lucas was married to a very very
famous script editor in the 70s and 80s
and they got divorced between then and
the the ones with the bad scripts and
there's a story about um I think they
were filming the final of the original
films and Harrison Ford is doing retakes
and it's because George Lucas is such a
bad script writer after about 30 texts
he's like George you can write this
but you can't say it and he storms
offset and that's exactly the same thing
that happens when people have a design
in their head but don't express it
visually and allow them themselves the
kind of the space and time to take it in
and respond to how it feels to use right
that's kind of the software equivalent
um so I don't think it's you know
categorically impossible to to come up
with some good apis without like
iterating them and seeing them but the
the odds are completely stacked against
you and all you're really doing is
cutting yourself off for an entire set
of
feedback so I guess with this kind of
stuff in mind and looking at this
framing device as software design as
just regular design it's probably worth
us thinking about the context that some
of our software is built in today versus
the context of the software that was
built at the time kind of the gang of
four books were written right it it
challenges some of the more classical
works of the genre we're not building
desktop software anymore we programming
languages have made categories of
problems obsolete most languages have
kind of functions as data um a lot of
those kinds of patterns are now gone and
we don't need them anymore because we
evolved much like the dis and the and
the telephone evolved into modern
smartphones and that's beautiful
actually now now I guess the thing is
when when I start to say things like
this all the 10th Generation clean
architecture folks just like really
really hate it right they they most of
the things
that and I'm I'm sorry in advents most
all of the things that you think are
best practice are just things that fit
your aesthetic sensibility one time
they're things you saw work once they're
just basically overblown structural
design patterns most of the time and
they kind of look as stupid as the
organization by technical concept
example from the start when you zoom out
it's it's a bit of a I don't know it's a
weird bummer like lots of system design
these days gets gets caught up into this
kind of decomposition clean AR
architecture Everything is Everything is
ports and adapters kind of pattern and
you know most systems have been atomized
into these big micr Services who am I
kidding they're all distributed
monoliths you do know that right if I
kick one over and the system goes down
it's not the thing um iest but people
describe all that stuff as best practice
right as best practice without saying on
what axis in what context for what use
for what people right like there's no
such thing best practice is a lie it
doesn't exist
so I want to show you another example
where the overall picture looks fine
when zoomed out but when you zoom into
the detail we we're living in The Divine
Comedy um so this is an application that
I was helping people fix recently again
you do not have to read the words just
look at the number of
boxes right it this is like a classic
prescriptive clean architecture like
handcuffing
conundrum but all I I actually see here
is like the telltale signs of complete
thoughtlessness right so what this is is
a system which we were trying to fix up
because it had build times of like 20
minutes and it was like it was an API
the whole thing was just an API but
there were like 13 C projects with then
13 common uh direct dependency libraries
underneath it for their Core Business
logic BL yeah and then a common Library
between them and then a library like a
core library that the common library and
the applications depended on I'm just
like what is all this and then I look at
the 13 Bill pipelines right one for each
application times three
environments test Solutions each
distinct for each of the things so it
was basically like 64 66 C projects and
one solution and the grand grand irony
was all of those like 13 * 3 whatever
that number is 929 Bill pipelines we're
all taking these applications putting
them onto the same physical machine with
the same lad balancer in front of them
so they were served as one app and I
walked in and I basically table flipped
she like why are you hurting yourselves
this whole thing was maintained by one
team of four people and I'm just like
who is who is this
four like is this performance art is
this like who why are you harming
yourselves you're sitting here and they
came to me because oh David the build
times are long
that's your problem cool cool that's
what you think the problem is
so the total cognitive load of
understanding this and all of those
moving
Parts which honestly I think were well
intentioned people did what they thought
was right and what they were meant to do
because they were given a right
answer was all done by this single team
and the irony is I opened up some of the
code files and we went through a
cleaning proc process later on
everything started looking like the
thing on the left became something that
looked like the thing on the right they
totally neglected the actual internal
hygiene of the code base in their
craving for these large scale
organizational patterns everything
looked good from 20,000 ft gold star but
like what this really is in my eyes is
people focusing on macro design rather
than the moment to moment form and flow
of code and it's horrible and you know
the truth is I I'm I'm over izing this
these were good people doing
well-intentioned work who I like very
much but I see stuff like this all the
time yeah I worked for 15 years as an
independent consultant and like so much
software looks like
this so how did we spot and fix this
right what we did is we first rounded
did a like a trim of complexity so we
collapsed all the families of modules
rolling them together so each web app
had one direct dependency we just mushed
those together we literally cut and
pasted the code into the same assembly
cool instantly half the footprint of the
system we then merge the test assemblies
half the footprint of the the test code
base and then all I did is I copied all
of the files into one app and deployed
it 13 times and just left all the
firewall rules to map as if it was
different apps and then once we knew
that work we deleted everything else and
then we had one app and that was it and
it took us 10 days really chainsaws out
to
fix 17c build
time because all that was really
happening was they were dying on the
font of
IO right like discs spin at a certain
speed you you can't copy megabytes and
megabytes of binaries and dependencies
64 times without it costing you
something and and I think it was all
this kind of well-intentioned high order
thinking that just I don't know they
forgot how software worked in the mix
and the team were really grateful and
they were like oh God this is really
obvious now and then then I left it with
them and they could use their
refactoring tools to quickly clean up
the code base and they could go through
and it was it was good and everything
was
collocated because what they had at the
start was obviously one system right and
I think all of this talk of kind of
decomposition and clean architecture has
dragged us to this place where we are
motivated to pull everything apart
without thinking that like you know
scalability comes at specific costs
right you separate things and you buy a
cost every time so if you just do it for
fun you're getting
nothing so so yeah that was what it
looked like at the end which is
objectively objectively very funny build
smaller
things so let's talk about the opposite
let's negate my argument there are of
course certain problem spaces where
there are well-known good structural
design patterns so the most glaringly
obvious example is kind of RPC style
systems like HTTP apis that often map
quite neatly to things like command
query patterns right they're they're
good right they're fine but the truth is
in those systems using wellknown good
patterns actually makes the form and the
flow and the organization of your
components even more important because
in any design where you make lots and
lots of things look the
same getting the bits that are different
to be obvious is your challenge right I
suppose what I'm reaching for is it's
not just what you say but it's also how
you say it and it matters because when
your ma macro level design is
comfortable people skim read right just
like would skim read in text if people
were were waffling in written word you
just skim past the content and you
missed the
detail and I think this is really the
the central problem with well-known good
designs is that like it's really easy to
learn a design pattern or two and then
and we've all been there and I'll tell
you why in a minute and everything in
the world looks like that thing you know
all of a sudden so let me tell you about
mistakes I have made in my career we we
we could feel like we're all in the same
boat together so I learned about MVC and
I thought everything was a controll
uh I learned about aspect oriented
programming and I thought everything was
chains of
interceptors um I learned about
pipelines and thought everything was a
pipeline with you know the middleware
patterns um I had a tech lead tell me
that oh controllers only ever talk HTTP
no business logic so then I thought
everything was an application
service and then obviously when
microservice design first got popular I
thought everything was a
microservice I have made many of those
mistakes Mes in my career all of them
repeatedly and it takes time to learn
that uniformity is actually the opposite
of
expressiveness and it's important that
when different parts of your software do
something different their form reflects
their difference they look different
that they cause you to stop and jolt and
change your approach visual variation
leads the eye it encourages reading
instead of skim
reading now intentionality is really the
opposite of complexity in in my mind
it's the stop doing things just because
stop cargo culting um I guess the thing
I try and Coach my teams when when I'm
doing like a a pairing code review is
like if you don't understand why you've
made a spe a particular choice don't
make it right don't make it until you
can justify that library or that
particular API or that approach if
you're just doing it because it's there
you you're probably wrong or you'll be
wrong
later um I guess the reason that people
make these quick choices is because so
much of software is context sensitive
that there are so many times where
blindly applying a design pattern makes
software more difficult to reason about
and our job when we're designing
software is fundamentally this war of
complexity
so one of the things that strikes me
when we talk about complexity is I'm a
little bit shocked at what things people
think are complex versus what things
people don't think are complex problems
so I read this really really great book
a year or two ago um so the book is
called a philosophy of software design
by a man called John ker how who is a
university lecturer who runs programming
courses as if they are literature
courses where he has people come in with
their code and he'll do a critique and a
marking and they'll come back and
they'll revise them like drafts and he
has this great chapter I think it's
chapter three in this book which really
gets to the heart of why complexity is a
problem in
software now complexity is anything
related to the structure of a software
system that makes it hard to understand
or modify the system sounds simple and
obvious but it's correct and it's the
central theme of this chapter that
complexity isn't caused by like a single
catastrophic error in your design
generally it's the tiny paper cuts that
accumulate over time it's kind of like
depression and happiness depression will
get you like a little bit but you'll
forget the happy bits right because
they're not quite as as moving in the
moment it's it it comes in from this
collection of depend Tendencies
obscurities and idiosyncrasies at work
is what he says so he describes
complexity as the thing that leads to
what the this this thing called change
amplification High cognitive load and
unknown unknowns leading to an explosion
of work and effort so that the number of
modifications it takes to build a piece
of software exponentially increases with
each added feature that's how you know
what complexity is and actually when you
build on that definition you think about
it there's lots of categories of things
that are complexity that you don't
realize
um I think thoughtful design is kind of
the Salve for
this but there's this distressing
realization when you start thinking in
this way you know design patterns
precisely got so popular because it
gives people a way to reach towards
something that they feel as good it's
like it's that um that teachers pet High
School thing where you've got a good
known reference answer you know nobody
ever got fired for buying IBM I used the
right design pattern technical leader I
did a good job please appreciate my work
but software doesn't really have many
definite conclusions in in it really and
and once you've seen enough code bases
in enough languages you you start to
realize that what most of the arbitrary
stylistic qualities of code that people
fixate on tabs versus spaces brace
style mostly irrelevant right actually
mostly irrelevant they're all um taste
really but instead you I I've ended up
focusing on these non-negotiable
qualities that I look for in code bases
that I think are far less regimented
than a style guide right I think good
code is code that's easy for someone
with minimal domain context to read
right code that your average developer
can understand is good code by
definition it's a communication form
code that focuses on developer
experience productivity debug ability
and usability code that you cannot debug
and you cannot change is bad code
doesn't matter how smart it is under the
hood
code where the intent takes up more of
the visual space than the language
constructs and syntax is good code so
code where you see all of the flow
control and none of the logic is code
that's hard to maintain so where you
bury your functionality under language
features and
ceremony and the truth is regardless of
kind of language style in or intent all
programmers interact with codebases the
same way right we open it up and we
glance at it and then we deep dive and
we read through it that's the workflow
that you always have to optimize with to
actually write good code and good code
by any met by those metrics makes that
job
easy
so at this meta level all code is
constructed from abstractions and
encapsulation the two things that we
have and regardless of programming or
ERA this has always been true so the
programming languages and run times and
Frameworks and operating systems that
you write higher level cod in today goes
through an enormous amount of
compilation and translation and like
there's there there's a million bits of
everything between your user land code
and the metal that you run on at the
bottom and you know programming
languages themselves are common
abstractions over operating system apis
which are which offer abstractions over
assembly languages of microarchitectures
and Hardware drivers and you know this
this trend continues upwards into the
functions that you write
and the types you define right so for
the most part we are blissfully unaware
that all this stuff is happening
underneath us but I want to use an
example for you that that illustrates
what makes a good piece of design right
so you never have to worry about what
happens when you call file open and if
you ever you know it's a bit of a like
I'm 14 and high and this is deep if you
ever thought about what happens when you
do file open like there's so much stuff
that happens underneath that call in
every programming language
right you have operating Pro programming
language apis operating system apis
device drivers so multiple different
categories of storage be they spinning
discs solid state drives memory SSD
trimming commands file systems different
kinds of file systems petitioning all
that stuff exists in the file open API
but you never have to comprehend it
because that API reduces the cognitive
load on the
user right so when we when we dig deep
into this
you can apply that same logic to any any
module right and Ander how calls this
concept the the idea of a deep or a
shallow module when he deals with
complexity he says that the modules of
any kind be they packages or apis things
that reduce complexity are deep modules
and things that amplify complexity are
shallow modules right so deep modules
are modules that offer a huge amount of
benefit for a very very narrow API file
open is exactly a perfect example of a
deep module the inverse is then also
true libraries and modules offer minimal
benefit with very very expensive apis
expose your application to an explosion
of complexity not because you're using
it all but you could be therefore the
the job on you to comprehend what's
happening when you interact with that
module so much greater
right
so as much a factor of avoiding the
wrong abstract is finding kind of the
right ones so generally any module of
code you find should contain a problem
space in its entirety that's what you're
aiming to do contain an entire domain
and you're not meant to leak any details
of the implementation of that domain
upwards right so it means abstractions
that include things like pass through
methods pass through methods have become
one of my like biggest massive red flags
in code bases because by those
definitions of deep and shallow modules
you're expose the 100% of the surface
area of the abstraction underneath you
and you don't give it a language or
provide any um Creature Comforts or
syntactic sugar to reduce that
complexity so you're literally just
amplifying the noise from the thing
above and adding just junk on top of it
so delete all of those rapper classes
right unless you're doing something
meaningful um the other tell is that
good deep modules never expose types
that they actually use in their
implementation because the types that
they use in their implementation should
be a lower order than the way that they
describe the output of that thing to
contain the complexity so all of a
sudden like I I read this chapter and I
sat and I I properly thought about it
for about a week I was like ah actually
all these categories of things that I
see in the software the things that give
me the ick that's what it is that's the
reason why I don't like these functions
that's the reason why these things are
easy to use super super useful and I you
know I think our software is kind of
riddled with thoughtless abstraction and
poor
encapsulation and every time a design
decision like that is made it decreases
the reason a module exists right um so
anything that adds large amount of
boiler plate to your system bad code and
you all already knew that but that's
why
now I guess you get to a certain point
where you realize that all talk about
design dissolves into discussion of
dogma and absolutism right because I
tell you the one true thing I know about
software design and I'll do this my job
title is distinguished engineer head of
architecture let me tell you what I
think about software architecture
there's no good design there is no one
design there isn't one doesn't exist not
true doesn't depend it doesn't
exist and any design when you stretch it
to its logical absolute extreme becomes
absurd right so the one true thing I can
tell you is if someone says they have
the right design for everything the only
thing I can tell you for a fact is that
they are wrong doesn't exist so
designing software with intention
software that survives is an exercise in
compromise it's always an exercise in
context it's always an exercise in
tradeoff and it's why everyone with any
experience in software design basically
just says it depends right it depends
how should I well it depends on what
well how many users what context what
cost how many people when are you going
to change it what does it do there's
about 30 different lenses you have to
look through your software out to
understand what it depends on to find
that good
design and you know a lot of the poor
trade-offs you will see in software uh
really involve people actively not
understanding the sources of complexity
in their own systems and that leads to
weird design doing things like taking
additional dependencies packages or
services for like single simple use
cases you know there's a lot to be said
about maintaining 30 lines of code that
you
own rather than a package you have to
deal with versioning and security
compliance and God knows what else to
solve one thing and you know all
dependencies have surface areas so if
you take a package all of a sudden
you've exposed your application to all
that dependency's
complexity now it's interesting because
that that sentiment oh just write it
yourself is directly at odds with the
other well-known and common correct
sentiment of well the best amount of
code you can write is no code right the
less you can write the better because
the less you have to maintain but the
truth is you know every line of code you
adopt is also code you own and I think
that's where it gets lost like cool
depend on a package but that's your
responsibility right you know so
something more constrained with a
smaller surface area pushes less
complexity into your applications
sometimes and that's kind of really the
thing you know the available potential
surface area of code that you are
exposed to is where complexity flows
from so I'll give you a really practical
example um I recently spent 4 hours
trying to evaluate every stat site
generator to make a fullpage website and
gave up and wrote a 30 line program
instead right because each one of them
was flagged as experimental or used a
weird view engine or like God knows what
dependency hell mpm chaos and I just
thought you know what I can write a
program that does everything I need to
do and I will never have to update it
and it's fine because I'm building a
full-page website right I just needed it
to read some markdown files I could
write that
simpler
so this is all about kind of the idea of
having your designs continually being
part of a tradeoff and what what you end
up with is instead of hard rules and
good designs you end up with tests like
psychological tests that you apply to
design to find out whether something is
good or bad um and I want to take you
through a few tests that I use to
evaluate designs um to help people find
the right answer for them so this is my
favorite one could you do the thing
doing with less moving
Parts less moving Parts generally better
because less things can go wrong when
there are less moving parts and that
again feels like a a contradiction of
like split your software up into small
pieces but it isn't moving parts are
process boundaries microservices
failable Parts it's actually kind of
better to have a system that fails as a
unit than fails as lots of individual
components if it's the same people that
have to diagnose the whole thing right
because you can you can diagnose that
locally if it's a single unit um there
are many places in our ecosystem where
ballooning complexity makes working with
our software just harder so we should
never extract things from our
application to somewhere else just
because like it comes with a cost you're
making a repository you're making Bill
pipelines you have release Cycles you
have patches and support you have people
that have to be on call as soon as you
snap a thing out that's a whole category
of problems you just
created sometimes it's the right answer
but do it meaningfully make a choice
that's
informed is it operable in a produ
production
environment like so many times I've seen
systems that have really asinine weird
esoteric requirements of their operating
and runtime this is getting better over
time mostly because Cloud vendors are
forcing people into very very narrow
boxes which is on average a good thing
um software systems are hard to observe
deploy and manage are basically dead
they're bad software right things should
be built to reduce operational burden
always is it easy to change
here's a truism for you the only thing I
can tell you that you will definitely do
with your software is change it at some
point right so software is hard that is
hard to change as bad software um and
what that means is you should really
avoid overdesign up front it's a little
bit of like the the classic yagy you
ain't going to need it right design what
you need for now because you know we
require designs that are easier to
modify rather than the premature
optimization of extensible Frameworks
and libraries and as programmers we
always get dragged towards building a
framework or a library because it feels
like the thing you should do the vast
majority of those extension points as
someone that has done this time and time
again in his career and never used build
with them in mind but don't Implement
them at the
start and I guess what I'm really
advocating for here I suppose when I
plead for intentionality is for you to
write software with care and
purpose um you know there was a I had an
exchange with someone that I that I
worked with with recently about some
error messages i' I'd built and like my
my school of error message writing which
I learned from does anyone remember ninj
the really good di container now Nate
Kahari who wrote ninject wrote the best
error messages I have ever seen in my
entire career because you do something
wrong with ninject it's like cool I
failed to do this here are the three
different things I tried here's the
stack traces from each one of them I
think you should probably try this to
resolve it and here's a link to the
documentation where we talk about this
concept and this error and I'm like cool
m class in error writing because it's
you know it's not just teaching someone
a fish it's throwing them a box of fish
at the same time um and I try and write
error messages like that it's like hi
you're here because you're missing some
environment variables here are the
environment variables you're missing you
probably need to make a file here or you
need to put them in this setting here if
you're on Linux do this instead that you
give them all the information in the
software it's the right place for it to
be and I think that kind of care and
purpose I I jokingly describe it as like
write write error messages like you're
in love with the person that's going to
read them and you don't want to ruin
their day right like it's a gentle human
thing and I want you to think about that
kind of design of your software and I
want you to think about the reader I
want you to think about what form and
flow do to your application and I want
you to realize that sometimes that
reader you're thinking about is you
right it's fine and I want you to use
all of the forms of expression you have
available in your codebase to
communicate meaning and intent in in
different you know problem spaces and
different solutions we require different
aesthetic viewpoints and different
designs signs and that's okay that's a
good thing otherwise we're damning
ourselves to the rest of our careers
just being either an MVC app or
everything is a big bunch of HTTP calls
or I suppose the third magic category of
like everything is just some react
components right the three
designs um but it doesn't have to be
that way it doesn't because I believe
that when you put the thought into your
code base the care shows right so I was
on a podcast a couple of years ago and
you know the end of podcast they always
ask you that like that one kind of gotta
question to try and try and elicit a
response and they just did the classic
oh what would you s to yourself 25 years
ago when you were getting started what
what advice would you give to
yourself and I think I know the answer
now I think I do take more
time take more time over everything and
I think the best software that I have
ever wrote where the care that I put
into it shows is where I finish and I
put a CD on and I pull myself put CD on
Spotify on um pour myself a drink and I
sit and I read it and I read it
obsessively and I read every line and I
think why did I do that why did I make
that
choice why did I make that decision why
that API why that form why that
organizational pattern and if I can't
explain it to myself I know I will not
be able to explain it to somebody else
and I change it and sometimes I change
it and I don't like what I see and we go
back to where I was because I think
that's the better compromise and that's
okay but giving myself that 20% extra
time at the end of everything to really
take it in and you know I think in this
kind of world that we live in where
people are are dragged into endless bike
shedding pool request kind of machine
gun fights with each other actually it's
a little bit of a kindness to yourself
because like at that point no one's got
anything on you in a pull request right
like you've you you've had that fight
with yourself 100 times so you know why
you're there um and I think all software
that's built with that degree of kind of
care and love for the
work means that we just never stop
asking
why I love it like and I think if I drag
us all the way back to the start where I
said like I was an art student like as
far as I'm concerned the software we
build although it kind of dra gets
dragged into these kind of Bleak
commercial settings for money and
survival it's our work it's the thing we
have when all this is done If I Were A
Painter I would have paintings when I
finish this I have software so it better
be what something I am proud of that's
kind of how I feel about it like deeply
so I want to leave you with a few
reading recommendations this is the the
slide to actually take photos of um
partially because I don't think there
are many books talking about this kind
of design but there are a couple I have
loved here um so the first this the
philosophy of software design it it is a
truly truly brilliant book and I think
the best work in this area code that
fits in your head by Mark Seaman very
very new I think it's three months old
talks about a lot of really really
practical applicable tips for your
software and and deals with a lot of
these kind of existential crises you
find on a momentto moment basis and then
your code as a crime scene um by Adam
torill um really really foundational
work of a former forensic psychologist
who talks about understanding the
knowledge flow of your software through
like doing analysis of commits and how
knowledge flows between people and
check-ins super super interesting um
brilliant books support authors that do
interesting work please and that has
been me that has been me this is the
talk it it depends I guess
basically that should have been the
title um thank you appreciate
it oh that's a lot sorry I know it's a
lot it's a lot and then there's not much
code but please green green in the Box
makes makes them make me come back and
get rained on next year it's
wonderful