# SOLID, DRY and KISS ### SOLID PRINCIPLES sources: - [stackify solid design principles](https://stackify.com/solid-design-principles/) - [baeldung solid principles](https://www.baeldung.com/solid-principles) Desing principles to encourage us to create more maintainable, understandable, and flexible software. #### Single responsability A class should only have one responsability. Furthermore, it should only have one reason to change. Advantages: - Testing. - Lower coupling. - Organization. Important question: `What is the responsibility of your class/component/microservice?` if the answer includes `and` then maybe we are breaking the rule. It is really general concept because, it can be applied to classes, components, microservices. Real example: **Java Persistence API (JPA)**. Defining a standardized way to manage data persisted in a relational database by using the object-relational mapping concept. Other functionalities which you might need to implement your application, like validation, REST APIs or logging, are not the responsibility of JPA. **JPA Entity Manager**. Its responsibility is to manage the entities that are associated with the current persistence context. [documentation](https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html) Personal Example: #### Open/Closed Classes should be open for extension but closed for modification. In doing so, we stop ourselves from modifying existing code and causing potential new bugs. The one exception to the rule is when fixing bugs in existing code. This means that I should be able to add new functionality without changing my existing code structure, but by adding new code instead. *Polymorphic Open/Closed Principle.* It should not inherit from the base class, instead the base class and the new class should inherit from an interface in common. #### Liskov Substitution If class A is a subtype of class B, we should be able to replace B with A without disrupting the behavior of our program. The principle defines that objects of a superclass shall be replaceable with objects of its subclasses without breaking the application. An overridden method of a subclass needs to accept the same input parameter values as the method of the superclass. Similar rules apply to the return value of the method. Apply this principle is a bit hard, becasuse the compiler only checks the structure, but not the behaivior. This requires all subclasses to behave in the same way as the parent class. - Don’t implement any stricter validation rules on input parameters than implemented by the parent class. - Apply at the least the same rules to all output parameters as applied by the parent class. #### Interface Segregation Clients should not be forced to depend upon interfaces that they do not use. Larger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need to be concerned about the methods that are of interest to them. Similar to the Single Responsibility Principle. It’s tempting to add a new method to an existing interface even though it implements a different responsibility and would be better separated in a new interface. #### Dependency Inversion The principle of dependency inversion refers to the decoupling of software modules. This way, instead of high-level modules depending on low-level modules, both will depend on abstractions. High-level modules, which provide complex logic, should be easily reusable and unaffected by changes in low-level modules, which provide utility features. Consists of two parts: - High-level modules should not depend on low-level modules. Both should depend on abstractions. - Abstractions should not depend on details. Details should depend on abstractions. ### The DRY Principle: Don't Repeat Yourself sources: [thevaluable DRY](https://thevaluable.dev/dry-principle-cost-benefit-example/) *Every piece of knowledge must have a single, unambiguous, authoritative representation within a system* A basic principle of software development aimed at reducing repetition of information. To avoid violating the DRY principle, divide your system into pieces. Divide your code and logic into smaller reusable units and use that code by calling it where you want. Don't write lengthy methods, but divide logic and try to use the existing piece in your method. Refactoring is is a good way to solve. It can be: - A precise functionality in the business domain of your application - An algorithm Summary: - Knowledge duplication is always a DRY principle violation. - Code duplication doesn’t necessarily mean violation of the DRY principle. As an example I have always tried to generate many classes or modules. - Controlers only invoce services classes or utility classes for responses - Services classes uses util functions and access data classes (like repositories) Posible errors, trying to apply DRY everywhere can have two results: - Unnecessary coupling - Unnecessary complexity You shouldn’t apply the DRY principle if your business logic doesn’t have any duplication yet. Again, “it depends”, but, as a rule of thumb, trying to apply DRY to something which is used only once can lead to premature generalization. for example in a react application, I have many pages with tables and modals (CRUD), so I think maybe could create a generic component which has all this functionalities, but it not was the better approach, because ... ### KISS: Keep It Simple, Stupid source: [interaction-design kiss](https://www.interaction-design.org/literature/article/kiss-keep-it-simple-stupid-a-design-principle) Is a design principle which states that designs and/or systems should be as simple as possible. The KISS principle is descriptive to keep the code simple and clear, making it easy to understand. Each method should never be more than 40-50 lines. Each method should only solve one small problem, not many use cases. The first usability principle for product design.