Showing posts with label software engineering. Show all posts
Showing posts with label software engineering. Show all posts

Friday, December 5, 2014

A Story about YAGNI - You-Aren't-Going-To-Need-It

Recently I was working for a project on a client where they wanted the project to be Live for a certain portion of time during the day - so for example between 9AM and 2PM, or 12PM and 3PM, or so on and so forth.

While implementing this feature, a thought struck me - what if the client wanted to have a period that ran past midnight - so for example between 11PM and 2AM? At this point, the intelligent thing to do would have been to pick up the phone and call the client to ask. Instead, I thought to myself - well, even if they haven't asked for it now, they might need it later. Besides, I could build a decent set of unit tests and use them to catch all the edge cases, right?

Wrong.

What ended up happening was that I spent many hours writing the unit tests to capture the many edge cases that came with crossing the midnight deadline during a time period. I spent even more time writing the code to deal with them. The project went over-budget thanks to that extra time I spent, and the client never ended up using the added feature. After a few months in production, the client scrapped the project (albeit for unrelated reasons). 

Lessons learned: unless you're very strongly confident that you need to build something for the future, don't do it. Don't fall prey to what-if's. Remember: YAGNI - you aren't going to need it. And if you do need it, you can build it later, when it's accounted for in the budget. Finally, don't be afraid to pick up the phone and ask a question. It makes everyone's life easier.

Monday, February 10, 2014

Thoughts on the Single Responsibility Principle



Today, while reading 97 things every programmer should know (disclaimer: affiliate link), I came across an explanation of the Single Responsibility Principle that finally clicked for me. I've read a fair amount of literature on Best Practices for programming, but I've often faced trouble in applying these best practices in real life projects. Here was an explanation that finally made sense.


The Single Responsibility Principle says that each class should have only one reason to change. This makes perfect sense in theory, but somehow I just couldn't find a way to implement it in practical code. However, after reading this chapter in the above book, I realized that I was getting the semantics wrong - objects in OOP don't have to correspond to objects in the real world. You don't need to have a single (possibly quite large) class for an Employee that handles the business logic related to Employees (eg. calculating wages, sick days, etc), as well as the database logic (inserting into and retrieving from a database), as well as any report generation logic - classes should be more flexible and correspond to what makes them easier to maintain. 

The chapter linked above, for example, says that instead of having an Employee class with functions that handle business/database/reporting logic, it makes more sense to have an Employee class that handles the business logic, then an EmployeeRepository class for the database logic and an EmployeeReporting class for the reporting logic. This means that if the database logic ever needs to change, I will only be touching the EmployeeRepository class that handles only the database logic. The business and reporting logic will remain untouched in their respective classes. Now, each class truly has only one reason to change.

Conclusion: don't be rigid in insisting on having classes map to real-world entities. Code your classes based on what makes them easiest to read and maintain.