20. the principle of segregation of design decisions
in a computer program that are most likely to
change, thus protecting other parts of the
program from extensive modification if the
design decision is changed.
46. other fun examples
• overriding responds_to? on Object
• un-defing id on Object (thanks Brian!)
• editing boot.rb in your Rails project
• using instance_variable_get anywhere
64. they are the only confidence you, as a developer,
should have in your code. whether it's an
acceptance test script written by a QA (manual or
automated) or the world's tiniest spec, this is your
starting point. without specs, the only assumption
you can reasonably make about your code is that
it doesn't work.
quality and entropy are the two themes underlying our talk.
Quality
how would you measure the value of a codebase? $ revenue generated? Time saved? LoC? None of these have a baseline against which you can measure success or failure
how would you measure the value of a codebase? $ revenue generated? Time saved? LoC? None of these have a baseline against which you can measure success or failure
The need to adapt software to changing realities is what drives feature requests. The quality of a static codebase doesn’t matter as long as it *works*
So... some part of code quality is encapsulation
is the code factored in a manner which allows tuning parts of it without affecting other parts
Which is encapsulation again
So what exactly *is* encapsulation
This is what we’ve been taught in college
David Parnas’ paper
This is a controller action. This is also really, really bad code. Is this familiar?
Which brings us to entropy
This is a controller action. This is also really, really bad code. Is this familiar?
As you work on a codebase the complexity of the code always increases and quality decreases. The difference is that unlike Physics, entropy increase isn’t constant - but more on that later, so hold your thoughts.
Let’s walk through this code quickly and see what’s the problem. We aren’t talking about fixing it - but just looking to understand the problems that exist.
Step 1 when dealing with ANY code - specs.
Ok, that’s good.
Coverage is good. It means we have *some* kind of safety net. How good that safety net actually is depends on how the specs were written, but lets defer looking into that for a bit.
This is a controller action. This is also really, really bad code. Is this familiar?
any method that has more handful of lines, or deals with more than a single concept is big. A one page method is an abomination.
This is a controller action. This is also really, really bad code. Is this familiar?
any method that has more handful of lines, or deals with more than a single concept is big. A one page method is an abomination.
This is a controller action. This is also really, really bad code. Is this familiar?
any method that has more handful of lines, or deals with more than a single concept is big. A one page method is an abomination.
Clearly this isn’t a good idea. And the people who wrote this would agree with me, and it was never their intention to get to this point. But they did, somehow, one if statement at a time and they started living with broken windows. That said, this could happen anywhere, in any language, right? Lets look at some Ruby specific fun and games involving the...
The Ruby programmer that starts to understand metaprogramming is like a Jedi apprentice with a lightsaber. Power without wisdom/experience. It appears that all problems are easily solved using a few quick slashes and hacks. For example...
Read the comment at the top of the page if you will. “This method is regenerated at runtime based on what the prefix is set to.” Uh, huh. And that’s a good idea how?
The metaprogramming lightsaber is fun, but sometime... ***? Like seriously, ***?
well, that’s a mechanic right there - the principle is that you need to wait until you have the judgement to apply the right tool for the job
Clearly, these are bad ideas. They might have seemed like good ideas to begin with, solving the problem quickly with a hiss and a sizzle. Even though they do solve the problem, they don’t do so in a manner that is well encapsulated, easy to spec and easy to understand. Over time, they act as points where cruft starts to accumulate.
eventually, you’re like the boiling frog. you did one little thing which wasn’t ‘clean’ as a quick hack, and then two months later you realise someone else saw it, though it was a good idea and replicated it everywhere. eventually you get
which, in a nutshell, is entropy on a codebase. After a while you can’t make any change without tripping over something (or someone).
entropy is a complex engineering problem
this is why Ruby codebases need more care and love than most other codebases
You need to know when, where and how to use the lightsaber
The point is... (next slide)
basically...
Step 1. Specs.
preferably one that doesn’t take too much time
Back to step 1. Specs.
no, seriously. we can’t emphasise this enough. with something as flexible as Ruby, you need specs.
Back to step 1. Specs.
As entropy on any code base always increases, it is essential to keep an eye on trends, and refactor/redesign every once in a while to make sure that it doesn’t go out of control
to make sure it doesn’t deteriorate like this
the trends you should watch
the trends you can quantify
the trends you should watch
the trends you should watch
the trends you should watch
the trends you should watch
reek
how long does it take a new person to get productive on your codebase