The purpose of this post is to outline some of the guiding principles of code we use at Buink. These principles inform how we review and write code and we ask all our contractors and employees use these as well.
Summary:
- Cost Effective Technology (efficient, maintainable)
- Responsive and Transparent Communication
- Quick Turn-Around
- Eloquent, Simple, Maintainable Code
- Less Code, Less Problems
- Intelligent Solutions
- Test Driven Development
Cost Effective Technology (efficient, maintainable)
One of the things you’ll notice as you read these principles is that almost all of them relate directly to making your code cost effective. I’m a developer, but I also call myself a business technologist because I’m constantly looking for ways to make:
- technology affordable for business
- business better with technology.
Focusing on cost effective code seems like a no-brainer, but you must realize that this isn’t the norm. Every day I see articles written about this or that best practice which may be bad for business.
I’ll give you an example: test driven development. I’m a huge fan! I love the benefits that tests can provide your code, but you have to understand that testing has trade-offs. Tests add about 30% to 40% of time to your project. This means your end-product costs more. So, if your project is a minimum viable product, then adding tests may be overkill. Also, tests can be done poorly. The big takeaway here is that testing is important but not for all projects.
Another example is WordPress. A big portion of my colleagues hate WordPress and actually mock WordPress developers. Why? Because they are threatened by the fact that WordPress comes out-of-the-box with tons of features they usually get paid to add. On the other hand, I look at WordPress as a tool perfectly suited for some jobs. If you’re looking for a simple site, I often call them brochure sites, then there is no need to code it from scratch. WordPress is a time-tested piece of software perfectly suited for the job.
This principle really sets us apart at Buink. I was an entrepreneur before I was a coder, so I see the trade-offs and try to educate my clients about them. I’m also constantly on the look-out for technologies (frameworks, platforms, etc.) that give more bang for the buck.
Responsive and Transparent Communication
Many of my clients are surprised when I add them to our internal project management software or give them access to the code during production. They’re also surprised how quickly I respond to email and how easy it is to reach me via phone, “call anytime” I say, and I mean it.
I find that being as transparent as possible with clients reduces misunderstandings and improves relationships.
I take communication to the next level by sending weekly invoices so clients know exactly how much of their budget is being spent. I also include a detailed breakdown of every minute of work in each invoice.
Quick Turn-Around
If you have a deadline, we’ll do everything we can to hit it. We’re not like other developers who try to manage their own schedule at the detriment of their clients. We’ll come up with a plan that works for your timeline and we’ll focus on hitting it.
Eloquent, Simple, Maintainable Code
Reading code can be a exercise in patience, particularly code that is not your own. Stringing functions together with intertwined dependencies increases the complexity of the code. Some people think complexity is just the nature of code. We don’t! The more complex the code is, the less readable, maintainable, and manageable. We strive to make our code simple and readable in the following ways.
Organized Code
There is a reason that organization is a synonym for business. Organization systematically reduces cost and increases benefit. With code there is no difference. Organized code is readable code, organized code is easy to maintain, and organized code makes us happy! 🙂
There is nothing worse than opening a file only to find a jumbled pile of mess (spaghetti anyone?). You have no idea which variables are used throughout the file and which are used only once. You have no idea where features start and stop. You have no idea which functions have which dependencies.
Our goal at Buink is to write code that you can get a feel for quickly. This is why we put the most important variables/functions/apis/references near the top of the file. We use setup functions to dispatch other important functions and to organize important variables. We use cutting edge technologies to separate components and make them reusable and updateable. We do all this so that your code lest costly in the long run.
Readability vs. Performance
At Buink, we operate under one simple rule: people are more expensive than servers. Hopefully this is self-evident, but if not, just look up the average price for a developer per year vs. the average price of a server. You’ll quickly find that it is much cheaper to throw more computing power at a problem than it is to throw another developer at it. This becomes less true when your site is getting billions of page views a year, but most projects won’t and don’t need to.
This doesn’t mean we throw best practices out the window. No! But when we need to decide between simple, readable, maintainable code vs. performance, we lean towards readable.
If performance does become an issue, we circle back and attack the bottlenecks that are hit by the end users most often.
Self Documenting
One problem with documentation is that it is constantly outdated. You make a quick change to line 300 and your documentation on line 1 is now misleading. I can’t tell you how many times I’ve tried to understand code and wasted money trusting the documentation. Things are constantly added, moved, changed, removed, and documentation is very poor at keeping up.
The only surefire way to keep your documentation up-to-date is to make it part of your code. With this, you cannot change the code without changing the documentation. Rather than spend time updating the documents, you spend time updating the variable names and function names. Then, when future developers take over the project, they find it easy to read and update.
I cannot stress how valuable a principle this is; this principle alone has saved our clients tens of thousands of dollars. This mindset isn’t easy to attain. It takes a little extra thought about what could be confusing for future developers and how can I write the code to make the intent clear, but this extra effort is well worth it.
Collapsible
One aspect of code that is often overlooked is proper indentation and closures. Most modern code editors allow developers to collapse code based on indentation. Writing code using closures and uniform indentation can allow a thousand line file to collapse into 6 or 7. Then you can drill down to the parts of the code most important to you. This speeds up development and reduces the overall cost of software.
Less Code, Less Problems
There are many ways to skin a potato. 🙂 There are tools and techniques you could use. Code is similar; there are always many options to accomplish the same task. Often, the first solution you think up/find is not the best. We’re constantly pushing to find the best, most intelligent, and simplest solutions to client’s problems. Reducing the lines of code is one technique we’ve found that skins our code potato well.
Building features with the least amount of code has many benefits including less bugs, less problems adding or updating features, and more clairty when reviewing code. We use the following strategies to reduce the number of lines in our code.
Code Reuse
The most important principle here is we NEVER copy and paste code. Ok, I’m exaggerating a little, but for the most part, the rule is to avoid copying. Whenever we’re tempted to copy and paste, we catch ourselves and start thinking about how we could make this into a reusable component or function.
This doesn’t mean that we just create reusable components for every little feature. A re-usable component costs a little bit more than a functional component and there is no reason to incur this cost if the code may never be reused. Also, making re-usable components reduces the readability and clarity of the code. For this reason, we wait to make re-usable components until we need them (i.e. until we’re tempted to copy and paste).
When reusing code, we strive to make it independent of its environment. In other words, we want it to plug-and-play in multiple areas of the website. We pay attention to adding default options to the code so it requires almost no setup and can be extremely customizable.
Code Refactoring
After building complex features/functions, we generally review the code to see if there is any ways we can make it more eloquent. Goal #1 is to get the feature working. Goal #2 is to reduce its size and make it more efficient.
Intelligent Solutions
Again, there are many ways to skin a potato. Some are more wise then others and the truth is most of the easy to find solutions are not good. Many of the previous principles can help us arrive at the smartest code, but there is still something to be said for thoughtful code. We don’t just find the first thing that works and throw it in. We have to consider the impact of our design on the whole system. How well does each solution address the overall business need? Is a solution forward thinking; in other words, will it set us up for success in the future or will it introduce technical debt?
Given the complexity of code, it is rare that future developers praise the code they inherit from us, and yet, that is our goal. To solve problems in such a way that enlightens those who read it.
Test Driven Development
Yes, tests are important and we push all of our clients to let us implement them. We’re constantly trying to improve our mindset around tests. Test driven development (TDD) is a buzz word these days, but 80% of the tests we see written by outside developers are useless clutter, and many time detrimental bloat. At Buink, we push our developers to think deeply about the type of tests that are valuable and the best ways to write them.