Practical Object Oriented Design in Ruby – Key Insights
This is for developers, programmers, coders, architects and everyone in between. Insights are language agnostic and the principles hold true for all object-oriented languages alike.
As developers, we write code every business day (and many times on weekends too as a hobby). Or oversee people who write code. We solve real-world business problems. Before I delve into how we should design our code, I want to briefly emphasize on why it matters so much.
Why Write Code With Good Design?
The world is ever-changing. So are its problems. And so do the solutions. The ideal way would be to solve a problem with code and never have to revisit it. But, alas, business requirements change or new requirements come to light and the solution needs to change accordingly. Writing well-designed code means being prepared for this change.
We do not aim to predict the change for that is a fool’s errand, rather we aim to design our solution such that it is malleable. This need for change is what makes design matter.
Design takes time and effort and returns benefits in the future. The point of time in future where time/effort sunk in design equals the benefits returned by the design is a break-even point. The goal of learning good design principles is to shift this break-even point for design in our favor.
The Ultimate Software Metric
According to Sandi Metz, here is the ultimate metric to measure the value created by writing code (and I personally recommend it)
Cost per feature over the time interval that matters
Emphasis on time interval that matters. If a lack of a feature will force you out of business today it doesn’t matter how much the poor design will cost tomorrow. Your business needs the feature today, you can deal with the code problems tomorrow as long as the business survives. This design compromise is like borrowing from the future, aka, technical debt. And like other forms of debt, this debt also accrues interest. I am sure most of the readers have distasteful memories of dealing with some form of technical debt.
How To Design For Failure
- Do not design (lol)
- Over-design: apply principles inappropriately and see patterns where none exist
- Separate the act of design from the act of programming
- BUFD (Big Up Front Design): predict the changes that may come tomorrow and try to code for them
How To Write Code With Good Object Oriented Design
This book is about objected oriented design. While I am a fan, there are other design paradigms that may better suit your solution or language of choice. I shall assume from now that you want to write good design in an object oriented manner.
Here is a list of principles that form the core of good design. I will expand upon them in detail in 2 upcoming guides lest this article become too long and drab.
- Single Responsibility Principle
- Dependency Injection
- Flexible Interfaces
- Duck Typing
- Roles and Role sharing
- Cost Effective and Object Oriented Testing
Maybe you understand some or all of the concepts already. Each of them is really simple but applying them to code has a beautiful and almost breath-taking effect. I can personally attest that I wrote better code after actively applying these principles in daily life.
I highly recommend watching this talk by Sandi Metz.