There is a story of three bricklayers. Each one was asked what they were working on. The first bricklayer answered gruffly, “Isn’t it obvious, I’m laying bricks.”
I glanced at the upper-right-hand corner on my laptop and it read 9:42AM. I kept nervously looking at the clock, and then at the mess of code in front of me trying to get my Mastermind game to work again. I had 18 minutes until my first project review for Turing School. What I had was a broken game, lines and lines of spaghetti code, and what little tests I had were broken.
The 18 minutes was not enough to salvage the project, and I was given the lowest score in every category. After at least a few nights of feeling disappointed in myself, I began to reflect on my failed project.
Starting off, the project seemed fine. I had a few methods and a class or two that I could easily keep track of. As I started to add more code, the complexity increased and I started to feel unorganized. In a rush to add more features to my game, I often ended up breaking other parts of the code and I couldn’t guarantee anything worked because I had few tests.
Throughout the entire project I had that nagging feeling like everything I was doing was wrong. I was taught by my instructors to name things well, to keep methods nice and short, to follow Test Driven Development. Under deadline pressure, though, I chose to ignore the things I knew were right, to try and finish. My way was the wrong way, and if I kept following this path it would have led to a lifetime of career unhappiness for me.
The second bricklayer replied, “I’m putting up a wall.”
Our first Rails project was a group project where we were tasked with making an e-commerce store. At this point I was mostly on board with following software craftsmanship principles. I followed TDD a majority of the time, tried to break things into smaller parts, and did my best to follow the conventions of the framework we were using. Programming started to be simpler and much more enjoyable using this approach! It was a struggle, but we finished the project and met all the base features that were required of us.
The next project required us to take another group's previous project, and use the existing code base to add or modify functionality. This way we could get a chance to work with legacy code. The group that inherited our project had a LOT of questions for us.
“Why is it named this way? It makes no sense.” “How come you have all these integration tests and not more unit tests?” “How come there is no validation for forms?”
Not only that, there were user experience issues with our application as well.
"How come I can pass in negative values at checkout for an item?" "The site looks fine on desktop, but I can't really use it in mobile."
The problem was we had built the project to meet the feature requirements from our instructors, but nothing more. Also, since we were all on the same team, we all had domain knowledge of how our application worked; but when given to someone else, a large part of it didn’t make sense to someone who has never looked at the code before. We not only had issues with our code, but our application only worked for those on desktop, and for users following the happy path stories we had created.
It was then I realized that being a good crafter means to write code in a way that will make sense to people who use our code after I am no longer there. It means having empathy for other developers. It also means having empathy for our users, and writing quality maintainable code goes a long way toward achieving that goal.
The third bricklayer replied, “I’m building the house of God.”
I was almost wrapping up my seven months at Turing, and had learned so much up until this point. I was getting better at TDD, SRP, and the SOLID principles. I felt like I was no longer following the path of a simple bricklayer, but following the path of a crafter of beautiful, well-maintained code. I wasn’t solely responsible for my own growth, though. I had instructors, mentors, and peers who poured thousands of hours of their own hard work to make me the developer I am today. I am extremely grateful for everything they have done for me.
As a way of giving back to the Turing community, we were assigned a capstone project that would somehow benefit our community. We built a job-finding application that used different APIs to help students look for their first programming role.
In this project, everything I had learned up until this point about being a better crafter came together. I learned the invaluable skill of stubbing out API calls in our tests after we hit our rate limit pretty quickly. I tested both the happy and sad paths, and thought of more edge cases when it came to user experience. The project had its hiccups, but for the most part our group was following good programming practices. In the end we built a project that we could be proud of, and that had meaning.
Part of being a crafter means giving back to the community. Achievement is fine, but fulfillment by helping others get better at crafting code is what being a crafter means most to me. Helping someone achieve that a-ha moment, or giving them advice on how to write tests, is a joy and a privilege.
Giving and receiving from a community of people who care about code will help turn you into someone who cares about code. If you want to join like-minded people who love their craft, join me at the Software Craftsmanship North America Conference. Be the third bricklayer.