Okay, go.
So this talk is not
actually specific for C++,
but what you going to
do, stand up and leave?
I don't think so, and so let's go on.
This is a little story
for you for starter.
It was a beautiful morning in the office
when I check out my email
and found out that most of our tests
for the latest nightly build was failed,
and I was like, "What? What's going on?"
and I quickly found out the commit
that was causing the troubles
and it turned out that
there is an open code review
for this commit, take a look on this.
It's actually a legendary
review in our company.
It contains 94 files, it has 94 files,
it has a dozen of reviewers,
169 comments, 26 hours spent reviewing.
And the beautiful title which mentions
bug fixing, improvements, and big changes.
(audience laughter)
So it's like what?
Very impressive.
So we know that's not how
you do changes, right?
So I'm just going to clarify why,
and what to do instead.
So imagine you are changing the behavior
or your little tiny lovely function
then we changes the behavior
or a class using this function.
We change the behavior of
a library using this class,
we change the behavior of
applications with this library,
which changes the behavior of the user
who uses your application,
we change the business process
built on top of this user.
So you can see here is that
impact of your single change.
And the impact is the risk,
and the risk is the probability
of you introducing a bug.
While for the sake of this talk,
and to make things more dramatic,
and to clarify its meaning,
let's say that if you
introduce the bug, you die.
So, you want to avoid both of this things
like equally, right?
So what happened?
You made a change which is observable
on each level of the hierarchy.
So this change actually
has an unlimited impact.
This is a functional change.
If you made the change that is observable
on several lower levels of the hierarchy,
it has limited impact,
and this is a refactoring change.
And the risk for functional
change is much more
than the risk for refactoring change.
Now let's use this
information on this graph,
graphs are awesome, right?
So on X axis, you have
lines of code touched.
And on Y axis you have the probability
of being dead after
touching this line of code.
(audience laughter)
Now let's place our review
from the example on this graph.
(audience laughter)
You're dead, right?
This is what you're going to be doing.
First what you need to do is
do a preliminary refactoring,
which touches many lines of code,
but which is less risk.
And after you're ready,
you actually do your risky change
but you touch much less lines of code.
And in this case,
hopefully you will survive.
Well, tests?
I have tests, I'm not afraid
of touching my code, right?
Wrong.
First of all, tests failed, okay?
But if you touched many lines of code,
what exactly did you do wrong?
Where exactly is your mistake?
Nothing we test can help you with that.
Then, you never have 100% coverage right?
And finally, it's much easier to check
that nothing has changed
than to check that the
change that was made
are actually correct.
That's why it is much
easier to write tests
for refactoring because with refactoring,
you change nothing.
So in a nutshell, when
you're going to fix a bug,
first of all, refactor your code
in such a way that the bug
is obvious, and easy to fix.
And only after that,
fix it with as little changes as possible.
If you're going to
implement a new feature,
first refactor your current architecture
in such a way that feature fits smoothly
in this new architecture,
and only after that
implement your feature with
as little changes as possible.
And of course, don't
forget to separate those
into several commits.
Speaking of commits,
I recommend to each commit
to have a particular
kind of change and these changes
are actually clarifications of changes
with limited and unlimited impact
that we were talking about.
And I recommend each kind
of change to be marked
with its own mark.
You place this mark in the commit comment,
and if you look at something like Gitlock,
you immediately realize
what you are looking for,
looking at, sorry.
And these kinds of
changes they map smoothly
on SemVer versioning,
and last but not least,
they require different
attention from the reviewer.
And attention of reviewers,
the precious resource,
and usually you want to spare this.
So, refactoring is great.
Preliminary refactoring is even better.
Do refactoring, be a nice guy.
Just like this one.
(audience applause)
