S - SRP - Single Responsibility Principle
- class should have just a one purpose - so for example
Animal
class shouldn’t perform logs to different outputs or shouldn’t perform a role of database of animals - don’t:
1 | class Animal { |
- do:
1 | class Animal { |
- animal class shouldn’t be responsible for database management like saving
O - OCP - Open/Closed Principle
- classes should be open for extensions (new methods) but closed for modifications (don’t change method) - I’d say, you can change methods but not the contract what they receive and return
- I’d say this role is more about abstraction and use of inheritance, for example by having a base class
Animal
with methodmakeSound
, which is going to be implemented by child classesLion
orSnake
- don’t:
1 | //... |
- You see, for every new animal, a new logic is added to the AnimalSound function. This is quite a simple example. When your application grows and becomes complex, you will see that the
if
statement would be repeated over and over again in theAnimalSound
function each time a new animal is added, all over the application. Do instead:
1 | class Animal { |
- another example:
1 | class Discount { |
- do instead:
1 | class Discount { |
L - LSP - Liskov Substitution Principle
- if something uses a class, it should be able to use the class and the base class / child class of it
- sub-class must be substitutable for its super-class
- PL: nie sprawdzamy typu klasy, wykorzystujemy metody wirtualne i implementujemy je różnie w róznych klasach, ale wywołujemy tak samo
I - ISP - Interface Segregation Principle
- you should write few interfaces instead of a big one interface that contains all the interfaces
- make fine grained interfaces that are client specific
- clients should not be forced to depend upon interfaces that they do not use
- PL: nie tworzymy metod, których nie będziemy mogli zaimplementować w klasach korzystających z interfejsu, np. przykład z
draw
vsdrawCircle
,drawTriangle
D - DIP - Dependency Inversion Principle
- you should create new class by placing in the constructor of it the interface of a class that the new class depends on
- PL: polegamy na interfejsach, nie ich implementacjach - aby można było podmienić lub zamockować