Skip to main content

SOLID - Design patterns

SOLID este un acronim de la:
SRP - The Single Responsibility Principle: o clasa ar trebui sa aibe o singura responsabilitate;
OCP - The Open Closed Principle: o clasa trebuie sa fie deschisa la extindere fara a necesita modificarea ei;
LSP - The Liskov Substitution Principle: clasele derivate pot sa fi inlocuite de clasele de baza;
ISP - The Interface Segregation Principle: interfete cu granulatie fina, specifice unei anumite responsabilitati, specifice unui anumit client;
DIP - The Dependency Inversion Principle: dependintele trebuie sa fie definite prin interfete si clase abstracte si nu prin clase concrete;

The Single Responsibility Principle( SRP)
"There should never be more than one reason for a class to change." — Robert Martin

O clasa trebuie sa faca doar in singur lucru si nimic mai mult. Fiecare clasa in parte trebuie sa aiba o singura responsabilitate. O clasa care are o singura responsabilitate este mai usor de modificat, mult mai usor de inteles si mai usor de testat. Totodata daca o clasa are mai multe responsabilitati avem mai mari sanse ca acelasi cod sa apara si in alte clase.
O clasa care are mai multe functionalitati este prea mare, face prea multe si este mult prea complicata. Cel mai usor lucru pentru a rezolva aceasta problema este sa facem split la clasa.

Open Closed Principle( OCP)
"Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification." — Robert Martin

O clasa trebuie sa fie deschisa spre extindere si inchisa spre modificare. Comportamentul unei clase ar trebui sa fie modificat prin mostenire si prin compozitie. Principala idee este ca functionalitatile logice sa fie cat mai bine definite, iar daca este cazul acestea sa fie mutate in alte clase si referite prin intermediul interfetelor.
De exemplu daca avem o clasa ce face validarea unui obiect, aceasta nu trebuie sa contina si regulile de validare. Acestea pot sa fie referite prin intermediul unei interfete si transmise prin constructor. In felul acesta daca regulile se modifica, nu o sa fie necesar sa modificam clasa care face validarea. Astfel regulile de validare o sa poata fi schimbate mult mai usor.

Liskov Substitution Principle( LSP)
"Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it." — Robert Martin

Ideea de baza este ca putem inlocui instanta unei clase cu subclasa fiu si totul sa functioneze normal. Nu este tocmai usor de facut acest lucru, deoarececlasa poate sa aibe un set de actiuni specifice care sa nu se mai regăsească in clasa fiu.
Un bun exemplu este exemplu clasic cu dreptunghiul si patratul, unde un patratul poate sa mosteneasca din dreptunghi dar laturiile deja difera ca denumire si logica.
Dar asta nu inseamna ca nu trebuie sa incercam sa respectam LSP. Trebuie sa incercam sa facem clasele de baza cat mai generice. Aceasta regula nu se aplica mereu, dar exista cazuri cand este foarte utila. De foarte multe ori nu putem modela obiectele exact la fel cum sunt in lumea reala prin mostenire, dar ne putem folosi de compozitie pentru acest lucru.

Interface Segregation Principle( ISP)
"Clients should not be forced to depend upon interfaces that they do not use." —Robert Martin
Fiecare interfata trebuie sa fie cat mai simpla si sa defineasca un singur lucru( sa fie specifice). In cazul in care avem o interfata foarte mare, cel mai bine este ca aceasta sa fie sparta in functie de ce responsabilitati are. In cazul in care avem mai multe functionalitati intr-o clasa, atunci in clasa respectiva va fi nevoie sa implementam toate interfetele de care avem nevoie. De multe ori daca avem o interfata foarte mare, clientul nu o sa aibe nevoie sa implementeze toate functiile, ci doar o parte din ele, a.i. se ajunge ca o mare parte din metode sa nu fie implementate.

Dependency Inversion Principle( DIP)
"A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions." — Robert Martin
Daca o clasa are dependinte fata de alte clase, acestea ar trebui sa fie prin interfete si clase abstracte si nu prin clase concrete. Prin acest mod clasele se pot modifica mult mai usor, o sa fie mult mai decuplata si mult mai usor de testat.
Daca respectam acest principiu, putem folosi Dependency Injection fara nici o problema. Totodata putem mult mai usor sa separam nivelele unei aplicatii.

Comments

  1. Ma tem ca Liskov substitution principle e un pic invers: se poate inlocui o instanta a unei clase de _baza_ cu o instanta a unei clase derivate (subclasa) a.i. toate proprietatile (preconditiile, postconditile, invariantii) aferente raman valabile (la nivel semantic, nu doar sintactic)

    ReplyDelete
  2. Catdespre Dependency Inversion, se poate formula si altfel, mai intuitiv: daca o clasa A are nevoie de serviciile unei alte clase B, prima clasa ar trebui sa defineasca o interfata I si doar sa se asigure ca obtine (sau i se furnizeaza) o instanta ce expune interfata I (care in practica va fi implementata de clasa B sau de un adapter ce apeleaza B).

    ReplyDelete

Post a Comment

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(...

How to audit an Azure Cosmos DB

In this post, we will talk about how we can audit an Azure Cosmos DB database. Before jumping into the problem let us define the business requirement: As an Administrator I want to be able to audit all changes that were done to specific collection inside my Azure Cosmos DB. The requirement is simple, but can be a little tricky to implement fully. First of all when you are using Azure Cosmos DB or any other storage solution there are 99% odds that you’ll have more than one system that writes data to it. This means that you have or not have control on the systems that are doing any create/update/delete operations. Solution 1: Diagnostic Logs Cosmos DB allows us activate diagnostics logs and stream the output a storage account for achieving to other systems like Event Hub or Log Analytics. This would allow us to have information related to who, when, what, response code and how the access operation to our Cosmos DB was done. Beside this there is a field that specifies what was th...

Cloud Myths: Cloud is Cheaper (Pill 1 of 5 / Cloud Pills)

Cloud Myths: Cloud is Cheaper (Pill 1 of 5 / Cloud Pills) The idea that moving to the cloud reduces the costs is a common misconception. The cloud infrastructure provides flexibility, scalability, and better CAPEX, but it does not guarantee lower costs without proper optimisation and management of the cloud services and infrastructure. Idle and unused resources, overprovisioning, oversize databases, and unnecessary data transfer can increase running costs. The regional pricing mode, multi-cloud complexity, and cost variety add extra complexity to the cost function. Cloud adoption without a cost governance strategy can result in unexpected expenses. Improper usage, combined with a pay-as-you-go model, can result in a nightmare for business stakeholders who cannot track and manage the monthly costs. Cloud-native services such as AI services, managed databases, and analytics platforms are powerful, provide out-of-the-shelve capabilities, and increase business agility and innovation. H...