Although today’s way of software development is rapidly changing, having a good understanding of these principles and good practices may only help you become better in software development. Personally, I would recommend to every solid Software Engineers to get familiar with these practices if not already.
- YAGNI (You Aren’t Gonna Need It)
- DRY (Don’t Repeat Yourself)
- SOLID principles
- KISS principles (Keep It Simple, Stupid)
- BDD (Behavior-Driven Development)
- TDD (Test-Driven Development)
- FDD (Feature-Driven Development)
This principle came from Extreme Programming and states for very simple things: Don’t overthink the problem solution in the execution stage. Just write enough code for making things working!
This principle follows and states for: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Basically, don’t replicate functionality in the system and do make your code reusable.
This principle has its own space in OOP. The SOLID mnemonic acronym represents these five design principles:
Design your classes in structural business entity/domain hierarchy, so only one class encapsulates only logic related to it.
Entities should be open for extension but closed for modification.
In the development world, any class/API with publicly exposed methods or properties should not be modified in their current state but extended by other features as needed.
- Liskov substitution
This principle defines the way how to design classes when it comes to inheritance in OOP.
The simplified base definition says that if class B is a subtype of class (super) A, then objects of A may be replaced with objects of type B without altering any of the desirable properties of the program.
In other words, if you have a (super) class of type Vehicle and subclass of type Car, you should be able to replace any objects of Vehicle with the objects Car in your application, without braking application behavior or its runtime.
- Interface segregation
In OOP is recommended using Interfaces as an abstracted segregation level between the producer/consumer modules. This creates an ideal barrier preventing coupling dependencies and exposing just enough functionality to the consumer as needed.
- Dependency inversion
The principle describes a need for abstract layer incorporation between the modules from top to bottom hierarchy. In brief, a high module should depend on an abstract layer (interface) and a lower module with dependency on the abstract layer should inherit/implement it.
Acronym for Keep it simple, stupid – and my favorite over the last years!
The principle has a very long history but getting forget by many Devs many times from my professional experience. Avoiding non-necessary complexity should be in every solid Software Engineer DNA. This keeps the additional development cost down for further software maintenance, new human resources onboarding, and the application/system additional organic growth.
Behavior-Driven Development is becoming more and more desirable practice to follow from the Agile oriented business environments. The core of these principles is coming from FDD. The BDD applies a similar process at the level of features (usually set of features). One’s tests build the application/system is getting a return on investment in form of automated QA testing for its lifetime. And therefore this way of working is very economically efficient in my opinion.
The fundamental idea of this is to engage QAs (BAs) into the development process right from the beginning.
This is a great presentation of the principle from the beginning to the end of the release lifecycle: Youtube
The software development process gained its popularity over time in test automatization. Basics are coming from the concept of starting the test-first and follow with the code until the test runs successfully.
Leveraging Unit test frameworks for this such as xUnit, NUnit (or similar), if you are .NET developers, helps to build a code coverage report very easily in MS Visual Studio (Enterprise edition) for example, which helps to build QA confidence over the code which last long time over the code releases.
Well know approach how to deliver the small blocks (features) in an Agile running environment. In other words, if you have a load of work to deliver is better to slice it down to individual blocks (features) which can be developed, tested and delivered independently.
The whole FDD methodology has 5 stages:
- Develop a model of what is needed to build
- Slice this model into small, testable blocks (features)
- Plan by feature (development plan – who is going to take that ownership)
- Design by feature (selects the set of features team can deliver within the given time frame)
- Build by feature (build, test, commit to the main branch, deploy)
The beauty of this development methodology approach is that deployment features such as Feature toggling can be integrated with relatively minimal complexity overhead. With this integration in place, the production team can move forward only on one main branch, unfinished feature development state regardless. An enterprise-level production team will appreciate this advantage, no doubt about it.
By following these principles and practices production team will produce maintainable code, with high test coverage and human resources high utilization over the SDLC (ROI).