Anything worth doing is worth doing well. “That’s Good Enough” isn’t good enough. There are some cases where you are writing a one-off script but those tasks are few and far between. Most people don’t get paid to write throw-away code. Most developers aren’t sysadmins writing procedural code on the level and complexity of Bash. Even if you are, is this the only style you know? Do you shy away from more complex tasks? Can you not break down an any size problem into smaller pieces?
A musician practices their art constantly. An athlete trains. And yet, we in the tech community have to go out of our way to find people who work on personal projects on the side or have the will/motivation to learn new things outside of “the job”. If you don’t learn on your own then you have to figure it out as you go. And you are already very busy so I know you’re just skimming over this post anyway. So let’s break this down in a bulleted list.
- Developers work best when they’re challenged but not overwhelmed. Optimal work is a run, not a jog or a sprint.
- Developers will step-up or fill-in a task to make it challenging as stated above.
- Your classic boss doesn’t really care how you solve problems.
- Culture takes 20 years to change.
- The Blub Paradox says (among other things) that you can’t make anyone understand the power of a different language because developers become sedentary.
- Good consultants are already busy so no one is going to save you.
- Training or bootcamps won’t change your skillset or habits by a large percentage.
Let me put this another way.
My cat will play with a toy on the floor. And after a while, it becomes boring. So she swats the toy under a cabinet. And now it’s exciting! She can barely reach the toy and its a challenge. When she gets the toy out, she’ll bat it under the cabinet again. What is she going to do? Be bored again? She’s good at reaching for the toy and using her claws to hook stuff, tail counter-balance to stay in control and seeing in dark places. She needs to be playing under the cabinet and not given an mouse in a barrel. This is what you must do. You must improve your skills by going beyond “Good enough”. Otherwise, you will stagnate and have limited tools and approaches to problems.
But how do you even know what to learn? When you are looking up and down the power continuum in a problem domain, how can you grow beyond your own knowledge boundaries to see advantages that other people are enjoying? If you were looking at a menu of pies, how would you choose which one you will like?
Here’s the pie menu. Pick the one that you like!
PIE MENU
(all pies come with whipped cream on the side)
---------------------------------------------
Cranston Ermu Supreme Pie
Tagasnackle Mound Blat Pie
Rumination Flip Pie
Rainclouds and Humility Pie
Are You Seeing The Problem Pie
$3.99 per slice
What? This is terrible. This isn’t fair. Certainly technology cannot be like this. This is computer science! How can you choose? How can you know?
Hungry: “Waiter. What’s in humility pie?”
Waiter: “Humility.” Hungry: “What does that mean?” Waiter: “Have you ever literally tasted humility?” Hungry: “No.” Waiter: “Well it’s kind of like tasting regret but also different than pride. You kind of taste like > you should have prepared more or set expectations lower.” Hungry: “That doesn’t make any sense.” Waiter: “Of course it doesn’t. It’s an experience. It’s not a definition.”
Given enough questions, the Waiter will quit unless the Hungry customer chooses a pie or leaves.
Now let’s look at some horrifyingly contrived personalities looking down (or not looking down) the pie continuum.
The Eternal Procedural Coder
Let’s say you are a developer who just writes scripts all the time. You piece things together and when they work the first time, you ship it (whatever shipping means to you). If a more complicated task comes along, you don’t change your design, tools or strategy, you just change the amount of time you throw at it. Once it works, you call it done.
- If you don’t know how to build something in a variety of ways then you are always going to build it the same way.
- If you don’t pre-learn outside work then you have to run to catch up to change your habits.
- You can’t train new developers easily on what you are doing because everything you build is “your way”.
- You can’t learn new techniques, tools or study good design because you don’t have time at work.
- You don’t feel like learning on the weekend or after work.
- When you look at another style, it looks like a bunch of crap and you don’t see the value/power/happiness/productivity/peace-of-mind because you haven’t gone through even one example yet.
Exactly what is the exit strategy here? What’s the end game? Who or what is going to save you or change your situation? What would the disruption look like? What would the disruption be called?
Meanwhile, you hate looking at old code. You wonder “what was I thinking?” or “I must have had a lot of coffee this day”. Projects come and go, you hope you never have to go back to old projects. You leave things alone because they are terrible but do the job. You continually start new tasks but they all come out the same. Huge single files, huge methods/functions. One mess after another. No wonder why they call this “work” right? Who would do this for fun or learning?
What’s interesting is that The Blub Paradox applies here too. It’s difficult to explain what development is supposed to be like to someone who has never had a success. Success breeds success. Failure is of course crucial to learning and courage is needed to fail when trying to succeed. But experience really is the success side of trying and learning. You can gain experience through failure but in terms of visualizing the ideal, success is very important.
The It Can’t Be Done Guy
Let’s say there’s a website called Searchbox.com that’s a stripped down version of Google. In a meeting, everyone is talking about how Facebook search and Twitter are all hot right now and you feel like you are behind the curve. So you decide you want to add friends, followers and other social features to Searchbox.com. Your rockstar lead developer says “it can’t be done”. No one questions him. The idea dies, jokes are cracked and the grapes were probably sour anyway. Yay team?
Software is supposed to be soft. So why can certain things be so easy and other things be so hard? I understand certain problems just “are hard” (concurrency, cache invalidation). But not even entertaining ideas or experiments could be a sign of bad design. Even with crappy procedural scripts, simple changes mean omfg-lots-of-lines changed. Design isn’t about avoiding change (and change will happen), it’s about reducing the cost of change.
If you want to learn from a master, read POODR. Sandi says:
…successful but undesigned applications carry the seeds of their own destruction; they are easy to write but gradually become impossible to change.
POODR is full of these insightful observations and Sandi doesn’t just give you advice. She walks you through refactoring code and demonstrates the concepts that are related to these insights.
Anyway, back to our example project. If searchbox.com is broken up into modules then there is a user class or object. Surely this class could be forked into a feature branch and worked on in isolation by a few team members to add Friend and Follower traits/mixins/interfaces? Or is the user really a session cookie combined with a database row and “who knows” how to change it?
If there isn’t really a concept of a user but it’s just a bunch of hacks then yes, no one is going to entertain massive changes to this concept of a “user”. It’s too hard (in your system). However, if a system was explicitly designed thoughtfully (not by default or by accident) then features are easy to add. The software stays soft. This is what Sandi is talking about in POODR.
The Waterfall by Default Guy
Let’s say there’s a guy in charge of a project. He hasn’t ever tried Agile of any sort. He’s read about it and he’s confident that he knows all about it. He thinks it sounds crazy, lazy and chaotic. He’s done plenty of projects in the past that have come out under-budget and on-time so why change anything? On the other hand, he’s not technical so his opinion of past projects is completely dependent on the feedback given to him by developers. If developers ever felt like talking to him was a waste of time then his opinion of how good “waterfall” is could be slightly off. The real question is, can you explain how delicious Agile Pie is to him?
Here’s the wheelhouse of agile type stuff.
- Developers aren’t going to want to work with you again if you burn them out.
- Project heroes burn out.
- You can’t hire your way out of a failing project.
- Most people don’t like the term Waterfall because it’s viewed old.
- If you don’t declare a methodology it’s Waterfall by default.
- You can’t do Agile. Agile is a type of thing. Like Car. You have to buy a type of Car.
So when you try to explain any type of agile techniques to someone who doesn’t have any experience with it, it’s the same thing as the Blub Paradox. The Waterfall Guy is happy enough doing no explicit methodology, why would he change? When asked how to prevent projects from getting off-track he will say, “before you start working on a project, you need to know what you are building”. Even though Agile (and common sense) says that both the customer and the developers are the stupidest at the beginning of a project. Big Design Up Front (BDUF) doesn’t work. BDUF is undesigned project methodology. BDUF is how you put together simple things like grocery lists and legos. BDUF isn’t how you deal with change and complicated systems where developers will upscale the project difficulty until it becomes interesting.
So even if you discuss these items with Waterfall Guy, he’s not going to get a taste of Agile Pie without eating it. You could talk all day long about the ingredients, how people keep eating it, how there’s these case studies showing it’s delicious. “Meh, whatever. I have my dessert already.” At the same time, Waterfall Guy is always asking for visibility as to what developers are doing through status reports. In his heart he knows that he has a few hero developers and if he loses them, he’s screwed. That’s ok, that’s why they call it work right?
The Non-Tester
There’s a team who are running a production app. They have a testing team. When developers are working on “omg the really important thing”, they tell the testing team to run “whatever test”. It usually involves someone manually going down a list with a pencil. When a problem is found then a tester will tell a developer something went wrong. “It showed me this error 0x2123 when I did the thing you told me to do.”
Except a lot of the time there isn’t anything wrong. A lot of times the problem is the testers aren’t developers. Otherwise, they’d be developers. A lot of times the tester doesn’t really understand the system and the developer has to explain the system to them. So while the developer is working on “omg the next really important thing” the tester is asking questions and the developer is getting annoyed. Jokes are made “you only come to me when there’s a problem, haha”. Or, “I bug you so much I owe you a beer! Haha.”.
Looking down the power continuum, a developer looks at testing libraries. They look annoying and time-consuming. Who needs this hassle? They don’t have time to find out if they do. They don’t understand the different levels of testing (from most involved and beneficial):
- No testing at all - you have to hit refresh in a browser and you have no idea if you broke anything else. Old bugs pop up.
- Some testing - unit tests but you have a team run through end-to-end scenarios.
- A lot of testing - you have unit and integration tests and maybe even code coverage reports and CI.
- Test-first development - you write your tests before code but that’s the end of that methodology.
- Test-driven development (TDD) - you let your tests completely drive the design of the system.
- Testing end game - You do red-green-refactor. Your tests run fast. You do UI testing. Your customer requirements map to easily read executable stories. You spend very little time in red. You ping-pong pair with TDD. No code is committed without passing CI. Your testing tools and process are constantly evolving in response to pain points.
The non-tester doesn’t see the value or the constant effort people are making to try to get to the Testing End Game. “I’m not a tester! Why would I test!” Meanwhile, they complain about how little time they have because they have to manually have to see if their code works. Or maybe they are embarrassed / mad / frustrated that they broke the development/production build. In essence, the Blub Paradox is telling us that they can’t see their problems through the lens of Blub because they don’t know Blub. Meanwhile, Blub (TDD) practitioners can’t imagine doing it the way the non-tester does it. In fact, TDD practitioners are honing their craft so much that it is a rare event when they’ll take the time to explain TDD or the End Game to a non-tester. Even if they do, both will be frustrated because any insight or evangelizing will be misunderstood.
The Long Time Ignorant
Take any of the above and put it in the context of time. How long has SQL been around? Does someone on your team not know SQL? Is it because they haven’t needed it? What if they are writing flat database files by hand and do need SQL? Have they just been living under a rock or can no one change their mind? What can you do as an individual to change such a blind eye?
How long has JUnit been around? Is there a Java developer you know that hasn’t written a unit test? Or they have written a few but they don’t anymore because they think they don’t have time to do it?
That Seems Hard
Someone who can only write code in a procedural style can’t break down problems into easily solvable bits. Without concepts like Mixins/Traits, Composing Behavior and TDD; a complex problem is just going to seem too hard. “I don’t do that kind of stuff.” When someone that has OO or Functional experience might say “here’s how I would do it, who wants to help me?” Of course there are things that are just too big but the difference is in experience. A Bash scripter isn’t ever going to understand ncurses events because they haven’t ever written a desktop GUI. So even though ncurses can be great for turning “scripts” into “programs”, they are going to shy away from ncurses because “wtf that seems hard”.
- You can’t explain the benefits of a web framework because of the Blub Paradox.
- You can’t explain the benefits of an ORM vs raw SQL because of the Blub Paradox.
- You can’t explain the advantages of tmux to someone because of the Blub Paradox. Even while they keep losing their ssh sessions over unstable wifi. Given a simple enough problem, you might be able to convince them to try it out.
Tmux is a perfect example. No one understands how great it is until they use it. Then and only then do they never want to go back. Tmux isn’t always great though. Sometimes the terminal gets all weird with certain keyboards or maybe you want the native buffer scrollback to work. So it’s not some silver bullet default. However, once you grok tmux, you know when to use it and miss it when you don’t have it. This is true for many things that people evangelize. However, sometimes you need to understand their world view and take that into consideration.
Tmux pie is delicious. Ask anyone who has tried it.
Answers
I don’t have all the answers. Ok, see you later. silence Well listening to Rubyrogues and reading POODR has given me some memorable advice which I’ll repeat here.
- Spike on foreign concepts. Ok, you don’t know OOP and breaking down problems. Make up a problem and do it. Don’t try to learn in your main project. Spike on a concept and throw the code away.
- Pair with someone who knows this stuff and check your ego at the door. When you are lost, don’t play with your iPhone. Ask questions. Pretend to be stupid. Check your ego.
- Learn a different tech stack. When I write Java (poorly these days), I bring Ruby experiences back with me.
- Watch conference videos and screencasts. Pre-learn before work. You have no choice. No one is going to pay you to get better.
- Read the POODR book even if you’re not a Rubyist.
- If you are resistent to an idea, change sides. Let’s say you don’t like soccer. Take the position of a soccer fan and argue with yourself. You might be amazed at the argument you make just looking from another perspective.