Basic Principles
Don’t Repeat Yourself (DRY)
Avoid duplicating code where possible. When a change has to be made to code that is duplicated in multiple places, every instance of that code needs to be found and updated, which could lead to inconsistencies and wasted time.
Keep it Simple Stupid (KISS)
Keep things as simple as possible while avoiding unnecessary complexity. Enterprise applications get complex fast. So, the simpler and more well-organized the code is to start with, the easier the application will be to manage when things become complex and confusing.
You Aren’t Gonna Need It (YAGNI)
Only add functionality when it’s required. Doing things that are not immediately required, such as arbitrarily splitting the application into a number of microservices before a good reason exists for doing that, may introduce more headaches. And those changes may need to be undone at a future date.
The SOLID Principles
The SOLID Principles, created by Robert C. Martin, apply to object-oriented design and provide guidelines for writing code that is more maintainable and extendable.
Single Responsibility Principle
The Single Responsibility Principle (SRP) states that every module, class, or function should be broken down into its smallest functioning unit and should have a single responsibility. Anytime a class or method is responsible for more than one thing, it should be refactored into more functional units, each having its own responsibility. For example, a single method should not be responsible for performing several complex operations. Separating those operations into different methods makes the code more readable and maintainable.
Open/Closed Principle
The Open/Close Principle states that software (e.g., classes, modules, and functions) should be open for extension, but closed for modification. Code should be extendable and should enable developers to add new features without having to modify the existing functionality. Object Oriented Programming makes this possible by using a variety of different techniques. For example, a derived class could override the functionality of an abstract base class to add functionality.
Liskov Substitution Principle
The Liskov Substitution Principle suggests that objects should be substitutable at runtime. For example, two classes that use the same interface are substitutable. Or, if S is a subtype of T, then objects of type T may be replaced with objects of type S. This basically means creating classes, and class hierarchies, that are interchangeable and do not compromise the behavior of the application.
Interface Segregation Principle
The Interface Segregation Principle suggests that clients should never implement an interface it doesn’t use, or depend on methods it doesn’t use. To avoid depending on unnecessary methods in interfaces, it may be best to separate unnecessary methods into separate interfaces.
Dependency Inversion Principle
The Dependency Inversion Principle (DIP) suggests that modules should depend on abstractions, not concrete details. Dependency injection is often used to abstract away the implementation details to prevent exposing unnecessary methods and makes the code more maintainable and portable. This provides the ability to swap out different versions of libraries, use mock libraries for testing or cloud development, swap out different technologies, and port those libraries to different applications and newer service Apis. DI depends on an Inversion of Control (IoC) Container, which does three things: 1) registers interfaces and implementations, 2) resolves the dependencies, and 3) releases resources.