If Your Code Looks Like This... You're A GOOD Programmer
Summary
TLDRIn this video, Dave Farley of Continuous Delivery discusses the concept of 'bad code' and its impact on productivity and system quality. He argues that good code should be functional and easy to modify. Farley emphasizes the importance of quality over quick, substandard solutions, citing data showing that higher quality code leads to more efficient feature development. He also touches on readability, complexity, and testability as key factors in code quality, using a real-world example to illustrate his points and advocating for modern software engineering practices.
Takeaways
- π Bad code is generally defined by its inability to perform its intended function or its difficulty to change when necessary.
- π The speaker argues that good code should be easy to change and maintain, which is more important than aesthetic appeal or over-engineering.
- π High-quality code is linked to higher efficiency and productivity, with teams producing better quality code spending more time on new features.
- π οΈ The professional duty of software developers includes building high-quality software efficiently, which is essential for long-term success.
- π‘ The script suggests that good code is not just about fulfilling its purpose but also about being easy to change, which is a foundational principle.
- π The importance of readability is discussed, emphasizing that the best code should be understandable by anyone familiar with the problem, not just the original author.
- 𧩠Complexity in code is managed by striving for readability and testability, which helps in maintaining modularity and separation of concerns.
- π Test-driven development (TDD) promotes code that is easier to change and maintain due to its focus on modularity and cohesion.
- π The script uses an example of real-world code to illustrate principles of readability, simplicity, and the use of TDD for creating maintainable code.
- π The concept of 'side effects' in code is touched upon, suggesting that minimizing them leads to more deterministic and simpler code behavior.
- π The speaker emphasizes the importance of continuous learning and improvement in software development, acknowledging that there's always room for betterment in one's code.
Q & A
What is the main topic of the video?
-The main topic of the video is defining bad code, understanding what it means, and exploring how to avoid it.
How does the speaker define 'bad code'?
-The speaker defines bad code as code that either doesn't do what it should or is too hard to change when necessary.
What are the two primary characteristics of good code according to the speaker?
-Good code is defined by two primary characteristics: it fulfills its purpose and is easy to change.
Why does the speaker believe that cutting corners to write code quickly is counterproductive?
-The speaker believes that cutting corners to write code quickly is counterproductive because it leads to lower quality code, which ultimately slows down development due to the time required to fix issues later.
What does the Dora data say about teams that produce higher quality code?
-The Dora data indicates that teams that produce higher quality code are significantly more efficient, spending 44% more of their time on producing new features than teams that do not produce high-quality code.
What is the speaker's view on the importance of readability in code?
-The speaker believes that readability is crucial and that good code should be understandable by almost anyone who understands the problem being solved, whether they are technical or not.
How does the speaker suggest achieving readable code?
-The speaker suggests achieving readable code by making each part of the code small and focused on a single part of the task, using descriptive names, and ensuring the intent of the code is clear to most people, including oneself in the future.
What role does test-driven development (TDD) play in writing good code according to the speaker?
-According to the speaker, test-driven development (TDD) plays a significant role in writing good code by promoting modularity, cohesion, separation of concerns, abstraction, and sensibly managed coupling.
What example does the speaker provide to demonstrate readable and well-structured code?
-The speaker provides an example from one of their pet projects, showing a small part of code that handles remote method calls. This example demonstrates small, focused pieces of code with descriptive names and clear separation of concerns.
What are some benefits of using modern software engineering tools and practices mentioned by the speaker?
-The speaker mentions that using modern software engineering tools and practices, such as working iteratively in small steps and using TDD, helps in achieving readable, modular, and easy-to-change code.
Outlines
π Understanding 'Bad Code' and Its Impact
Dave Farley introduces the concept of 'bad code' and its implications on productivity and system quality. He emphasizes that bad code is either non-functional or difficult to modify, and argues for the importance of creating good code from the start to avoid future issues. Farley also discusses the misconception that cutting corners leads to faster delivery, citing data that shows high-quality code production correlates with higher efficiency in feature development. The video aims to explore the definition of good code, practical steps to build it, and the pitfalls to avoid, using real-world examples.
π Defining Good Code and the Importance of Readability
The second paragraph delves into the characteristics of good code, suggesting that it should fulfill its purpose and be easy to change. It critiques the common lists that define bad code, proposing a more fundamental definition. Farley discusses the concept of readability, asserting that good code should be understandable not just by its author, but by anyone familiar with the problem it solves. He uses a personal project as an example to illustrate how code can be structured to be readable and maintainable, emphasizing the importance of clear naming and separation of concerns.
π οΈ The Role of Testability and Modularity in Code Quality
In this section, Dave Farley highlights the importance of testability in managing code complexity and ensuring quality. He explains how adopting test-driven development (TDD) promotes modularity, cohesion, separation of concerns, and sensible coupling. Farley uses the same real-world code example to demonstrate these principles in practice. The code is modular, with each component dedicated to a single task, and changes can be made easily without affecting other parts of the system. He also touches on the object-oriented nature of the code and the absence of side effects, contributing to its simplicity and predictability.
π Embracing Modern Software Engineering Practices for Better Code
The final paragraph wraps up the discussion by emphasizing the value of modern software engineering practices like iterative development, test-driven development, and focused design experiments. Farley reflects on his own coding style, which results in simple, focused, and easy-to-understand code. He invites viewers to learn more about these practices through his book and encourages supporting the channel through Patreon. The summary underscores the benefits of writing code that is not only functional but also adaptable to change, which is crucial for long-term software maintenance and evolution.
Mindmap
Keywords
π‘Bad Code
π‘Good Code
π‘Continuous Delivery
π‘Productivity
π‘Quality
π‘Professional Duty of Care
π‘Readability
π‘Complexity
π‘Test-Driven Development (TDD)
π‘Modularity
π‘Separation of Concerns
π‘Abstraction
π‘Scalability
π‘Resilience
Highlights
Dave Farley introduces the topic of defining 'bad code' and its impact on productivity and system quality.
Bad code is characterized by its inability to perform its intended function or difficulty in making changes when necessary.
Good code should be easy to change and maintain, directly impacting the bottom line and feature development speed.
High-quality code is linked to higher efficiency, with teams spending more time on new features, according to Dora data.
Software professionals have a duty of care to build high-quality software efficiently, avoiding the trap of cutting corners.
Sponsorship acknowledgment for Equal Experts, Transic, and Semaphore, companies aligned with continuous delivery and software engineering topics.
Chat GPT's definition of bad code is discussed, emphasizing maintainability and the ease of making changes.
Good code should fulfill its purpose and be easy to change, with other qualities being special cases of these fundamentals.
The importance of context in defining code quality, such as resilience and uptime, which may vary depending on the business.
Common lists describing bad code often start with readability, but true readability extends beyond the author's understanding.
The best code is readable by anyone who understands the problem, not just the technical details.
An example of readable code from Dave Farley's pet project is presented, demonstrating clear intent and structure.
Readability is enhanced by small, focused code parts with descriptive names that convey their role in solving the problem.
Test-driven development (TDD) promotes modularity, cohesion, separation of concerns, and manageable coupling.
The example code is modular, making it easy to change and extend without impacting other parts of the system.
The importance of avoiding side effects and using final state for objects to ensure deterministic behavior.
The example demonstrates the use of modern software engineering practices to achieve simplicity and ease of change.
Invitation to learn more about software development practices through Dave Farley's book.
A call to action for Patreon support to help with the production of the channel's content.
Transcripts
we all say it that code is bad this code
is terrible but what does it mean and
what should we do about it that's our
topic for
[Music]
today hi I'm Dave Farley of continuous
delivery and welcome to my channel if
you haven't been here before please do
hit subscribe and if you enjoy the
content today hit like as well bad code
is probably a bad name for bad code but
at least collo
if not technically we all know what we
mean when we say it that is not how I
would have done it or if it's our code
that's bad it's not how I'd do it now
with the benefit of hindsight bad code
is code that is difficult or at least
unpleasant to work on in this episode I
want to explore what bad code really is
what's a sensible practical definition
for good code and what it takes to build
good code and avoid traps in Bad Code
based on some real world examples
fundamentally bad code is defined I
think by two things either it doesn't do
what it should or even if it does do
what it should it's too hard to change
it when we need to change it I'd argue
that that's it everything else is
secondary to those two things if it does
what it's meant to and it's easy to
change then it's good code this is not
about engineering as art or over
engineering or software developers being
over precious about the the beauty in
their code this is practical pragmatic
stuff it works and it's easy to change
these things have a direct bottom line
impact on the productivity as well as
quality of the systems that we build if
you want to go quickly and build lots of
features you don't get to do that by
cutting corners and writing bad code
fast you do it by working more carefully
to create good code from the start and
so saving lots of unnecessary time and
effort correcting the Fallout that your
bad code cause later on I wish that more
of us techies believed that and defended
that idea more strongly to misguided
people pressuring us to cut Corners to
deliver faster because cutting Corners
simply doesn't work the Dora data says
that teams that produce higher quality
code are significantly more efficient
overall spending 44% more of their time
on producing new features than teams
that don't 44%
that's a big win quality matters for
commercial reasons because we go faster
overall and we create better quality
code so as software professionals we
have a professional duty of care to do a
good job this is not about
self-indulgence or over engineering this
is what we are paid to do our
professional duty of care to build
software as efficiently as we can to do
that we need to build high quality
software not create crap quickly because
if we optimize to build crap quickly
then the data says that we just end up
building bad software more slowly the
worst of all possible
outcomes let me pause there and say
thank you to our sponsors we are
extremely fortunate to be sponsored by
equal experts transic and semaphore
equal experts is a consultancy built on
the idea of applying the techniques that
we talk about here to build great
software for their clients transic is a
financial technology startup applying
Advanced continuous delivery techniques
to deliver low latency trade routing
services to some of the biggest
financial institutions in the world and
semifur are leading suppliers of
cloud-based deployment pipeline
Technology support for your projects all
of these company offer products and
services that are extremely well aligned
with the topics that we discuss here
every week so if you're looking for
excellence in continuous delivery and
software engineering please do click on
their links in the description to below
to show them your support so if bad code
is so important what is it and what do
we do to avoid it here is chat gpt's
take on defining bad code it's not
perfect but it's also not a bad summary
either so if bad code is hard to
maintain then clearly it isn't easy to
change if it has scalability issues then
it doesn't really work as it's meant to
and all of these other things also fall
into my two categories of of doing what
it's meant to and then being easy to
change which I think are the simpler
more foundational and more useful ideas
fundamentally good code needs to fulfill
its purpose and be easy to change
everything else is just a special case
of those two things it's possible that
I'm being a little bit overly reductive
here but in this case I don't really
think so because I can make my code
scalable or write it to eliminate
security vulnerabilities and it still
might be bad code if it's hard to
maintain or offers a poor user
experience so if we fix all of these
things is the code good now well maybe
maybe not to achieve good code our code
needs to fix all of these things and
depending on context probably several
more not listed here if uptime matters a
lot to my business resilience may be a
much more important defining
characteristic of my systems quality
than say scalability so code that isn't
resilient is bad too but that isn't
covered in this list in this case a
detailed list is less helpful really
than a generic statement of principle
because we may always miss something off
the list so although bad code is often
defined with lists like these these
aren't really definitions but rather
only reminders of some of the things
that we probably need to get right
depending on our context but using the
more fundamental definition of code as
something that fulfills its purpose and
is easy to change is always true so I
think he's a much more useful tool to
help guide our choices but let's dig in
a little bit deeper than that most lists
of things that describe code as bad look
something like this and often they start
with
readability the problem with this is
that it's my impression that what we
mean when we say readability matters
when comparing good code and bad is
often rather ironically Lost in
Translation I quite like this from the
C2 Wiki and one of the most amusing
things about it are the comments there's
a link in the description to those if
you want to check them out the comments
argue quite a bit about the ins and outs
of these five lines of code and the
coding practice exhibited by them which
goes to show that good and bad are
somewhat subjective ideas when we get
too lost in the detail the code that
fulfills purpose and code that's easy to
change are a lot less
subjective closer to real measures of
practical outcomes that really matter to
us but back to my current Point
fundamentally readability doesn't mean
that you the author can read it of
course you can in the moment that you
wrote it you must be able to read it
otherwise you couldn't have written it
but that is nowhere close to good enough
not a high enough bar to strive for
readability means cons considerably more
than that I think that the best code is
readable by almost anyone who
understands the problem being solved
technical or not if you're writing
medical software a non-programming
doctor would understand the core logic
of your system with some help if you're
writing a game a game player should be
able to follow the logic of your
reasoning again probably with some help
I think that this is a good sanity check
to think of the least technical person
who understands the problem being able
to read and understand the intent of the
code I don't always achieve that in my
own code but I think that I usually
write code that I could at least easily
explain to them here's an example from
one of my pet projects this is a
technical code but Within These
constraints I think it's readable so
let's try that out this is a small part
of some infrastructure that is meant to
take a Java class and use it to generate
remote calls and remote proxies to
handle those remote calls translating
them into calls into a service this code
is on the receiver end of one of those
remote method calls and so represents a
translation from a remote call of some
kind into a local call to the code that
actually does the work none of this
matters very much except as scene
setting context so that you can
understand the goals of this code the
class is a runtime translator and here
we are registering the service that has
the method that does the work and
creating a translator for one specific
method call within that service
identified by the method parameter to
this Constructor I know that I'm largely
just read repeating what the code
already says but that is kind of the
point I think that this is all that you
need to know to put this code into
context but let's look at the next layer
down and note this code is internally
layered and named so that each part is
focused on only one part of the job we
have a layer of abstraction within this
class public methods that orchestrate
the work private methods that then do
the work so now what we want is to
create a collection of parameter
decoders is the code for that and sure
there's some technical boiler plate
imposed by Java here for creating fix
size arrays and so on which we may have
to explain to our non-technical reader
but for a moment try and separate the
meaning of the intent of this code from
the plumbing of how Java works the core
of what is happening here the plumbing
aside is I hope pretty clear even to our
non-technical reader we're creating a
new parameter decoder for each parameter
and saving it for later use here's the
code that uses it later when a method is
invoked this code is called and it
iterates over its predefined list of
parameter decoders that that we stored
earlier and uses them to decode each
parameter in turn and then it makes the
method core with those decoded
parameters there are several things that
I think help this code to be readable
each part of the code is small and
focused on a simple part of the task
I've chosen names that I aim to be
descriptive in terms of the problem and
their role in solving it given the
context of the problem I'm aiming for
names that are meaningful and
practically given an understanding of
the context clear enough that their role
in solving the problem is clear to most
people including me in the future and in
that last respect this code was indeed
readable because I wrote this some years
ago and still understood it well enough
now to try and explain it to you I think
that this counts as readable code second
in this list of common problems though
with bad code is complexity striving for
readability in the sense of easy
understandability helps us to manage
complexity certainly but even more so
working to prefer testable code helps
with that to by adopting test driven
development it's difficult to avoid
preferring testable code in our designs
it promotes greater modularity cohesion
separation of concerns abstraction and
sensibly managed coupling it's hard to
write testable code that doesn't
demonstrate those features let's look
again at my very simple real world code
as I said this is part of a real world
personal project it's not written as a
demo for this video that's why I chose
it I developed it from scratch with test
driven development and it works and does
what it's meant to do but it's also very
easy to change because it is modular
it's a collection of several small
pieces each one dedicated to a small
Single part of the overall task so it's
also cohesive and has good separation of
concerns because each part does one
thing and everything needed to achieve
that one thing is within the small
relatively simple piece of code each
piece of code interacts with others
through abstractions that hide
information The Constructor delegates
the most complicated part of the
initialization to a private method
that's clearly named for what it is that
it achieves in the context of the
Constructor that allows me to keep the
intent of the Constructor clear to any
reader these abstractions hide
information depending on the fewest
simplest parameters to get the job done
so even internally it's also minimally
coupled to achieve its job and each part
of the code even at the level of methods
within a class is abstracted from every
other so that I can change any single
method with minimal or zero impact on
the others there is more to even these
few lines though this code is clearly
objectoriented in terms of design a
react service method is an object and it
contains a collection of instances of
parameter decoders which are abstract
and polymorphic and aimed at decoding
specific types of method parameters
there is a state and behavior here so
it's definitely objectoriented but look
a little closer this code also has no
side effects all of the state in these
things is created during its
initialization and is declared final
which in Java means that it won't change
once it has been initialized so the
state never changes for a given instance
this too limits unexpected changes in
Behavior later and even though it's a
functional idea perhaps here I'm using
it in an O system so this code is
behaviorally simpler and so more
deterministic as a result I'm not using
this code to boast about my design or as
an example of perfection I'm sure that
there are ways that it could be better
I'm always sure that there are ways that
my code could be better I don't know if
you will agree with me or not that it
it's able and less complex but even if
you don't given that it is well unit
tested as a result of being built with
tdd from the start I hope that you will
agree that this Cod is certainly easy to
change for example I can trivially add
support for new parameter types if I
want to without changing any of the code
that I've shown you so far and because
of the separation of concerns in my
design you have no idea how the
transport of the data representing a
method core works or how messages are
rooted between caller and receiver these
are indeed separate concerns and so
don't impact on this part of the code at
all I chose this code because it's real
world not some artificial example this
is what my code tends to look like when
I write it I also chose it because I
think it demonstrates what I mean about
using the tools of modern software
engineering to guide me towards what I
think are better results by working
iteratively in small steps and using
tests via test driven development and
small focused experiments in Design This
is the sort of code that I tend to end
up with if you'd like to learn more
about that and how to do it do check out
my book each part here is consciously
designed to be as simple as I can make
it each part even each function method
or variable is focused on doing one
thing and so I think that all of these
things help to make this code easier to
understand more readable and so more
likely to achieve my goals for the code
whatever they may be they also make the
code much easier to change when I've got
something wrong or the circumstances of
the use of my code change and require me
to change it to match them thank you
very much for watching and if you're not
already a patreon supporter please do
consider joining and supporting our
Channel and and our production of this
content and thank you to all of our
existing patreon supporters so far there
are lots of benefits to joining as a
patreon member and lots of additional
information that you can gain from there
thank you and bye-bye
[Music]
5.0 / 5 (0 votes)