YAGNI likes a DRY KISS
There are several acronyms which would definitely help to review code and design, improve it or confirm discussed decisions, because they actually are design paradigms and proven good practices. It’s hard to combine all of them in one easy-to-remember sentence and we wont create yet another super acronym or geek alphabets, even because the presented list is not comprehensive of all the available ones. However, many of them are worth to keep in mind and be considered when approaching refactorings and evaluating good practices. Let’s have a look at the proposed well-known acronyms:
- SRP: Single Responsibility Principle. You can apply it to a class, a package, a component or a subsystem, no matter the granularity of your interest, there is always a domain, a business requirement to meet, and that’s the principle you should try to apply: don’t mess with responsibilities, try to identify and provide a single responsibility and you will certainly remark how easier will be to reuse the concerned class, to test it, to document it. Applying SRP, you would indirectly meet the Law of Demeter as well, lowering the coupling of your component (because you limited it to one and only one responsibility).
- DRY: Don’t Repeat Yourself. Remember this acronym when starting duplicating code once again, when repeating the same test more than once: it will help you to achieve more reusability and automation, to collaborate with team members in order to check whether or not the same functionality or a similar one is already available and identify refactoring and improvements. And watch out: if you aren’t DRY enough then you might be WET (Write Everything Twice).
- KISS: Keep it Simple, Stupid. I would personally avoid the last adjective, but that’s it, the acronym is well-known as it is presented and indeed you should never overcomplicate design or code, considering different approach and trade-off and finally choose the simplest one, given system constraints and business rules. If you KISS, you will definitely improve testability and your code would probably be self-documented and much easier to refactor in the future, if required. And you would automatically meet the POLA paradigm as well, Principle of least astonishment, that’s it, providing contracts, interfaces, components which behave as expected, as the user would predict. You will hence improve your usability too.
- TDA: Tell, Don’t Ask. Think about a class which only provides get/set methods, anemic code indeed, it would not have any behavior, it would actually represent a collection of states and it could be fine for ORM entities (unless you don’t consider a DDD, Domain Driven Development approach), but it would lead to procedural code and interactions if extended to other type of classes. That’s it, the TDA helps you to maintain an object-oriented design and think in terms of behaviors, verbs, actions you would tell to execute to a given object and not just asking for values, states, properties.
- YAGNI: You aren’t gonna need it. And if you don’t need it now, you should not waste time and energies on it. That’s the acronym to keep in mind when starting adding a not requested feature, an additional super flexible design which would probably never be required but which would definitely add effort and time to testing, debugging, documentation, justification to the customer of any matter related to the concerned component. You should try to KISS indeed.
KISS and DRY are probably easy to remember, because of their existence as real words, but try to keep all of the above in mind, somehow. A good attitude at end of each development or design phase, would be to ask ourselves whether or not the class, the package or the concerned component was meeting the SRP paradigm, whether or not we were DRY enough and the level of our KISS or if you played consciously with YAGNI. Of course, we often need to provide much more than required in order to have a flexible and extendible architecture, forecasting probable entry points and anticipating business needs, hence YAGNI is not always a good practice. TDA as well fails on most of the ORM entities implementations, but as with design patterns your experience and your project competencies should help to decide whether or not one of these design paradigms could be skipped for a certain component and scenario. And you could also play with your colleagues, inventing strange and funny comments about their DRY attitude, just don’t mess too much with KISSes though.
Can you share some examples? But not about Shape and Rectangle, rather something that required you to make trade-off. And discuss how following the rules lead to better code/design.
I just see every day KISS understood differently by each developer, so articles like that does not help with anything.
Can’t wait the followup :)
@ Indeed, KISS does not always lead to the same simple solution. No shape, no rectangle, think about a cache management. Real life example to share: a Struts Action received from an EJB a list of user details using pagination (you wont load the whole table, KISS), however due to wrong design the query to dig into a certain list item takes longer than expected. Developer1: let’s write a custom cache at Struts Action level, we shouldn’t invoke twice the EJB and load twice the same details if that takes too long (DRY?). Developer2: No, you don’t need yet another… Read more »
Thank you for the example!
One developer refused to extract a class (keeping functionally in private method instead) which violated SRP… two times (class had at least 3 responsibilities after that).
Should we ban KISSing? This kind of rules must not be an excuse for bad decisions.
Indeed, KISS can lead to bad decision if not used consciously, I definitely agree. In the name of KISS, developers could justify everything! In general, it would be always better to double check the pairs KISS-SRP or KISS-YAGNI, but also KISS-DRY. Another example: in the name of KISS, a developer could justify duplicating a functionality, as private method, just because the functionality’s supplier was not available at that layer and it would make code a little bit more complex to use it: wrong! KISS should be also proven by component’s testability and usability. Thank you very much for these comments,… Read more »