https://github.com/domnikl/DesignPatternsPHP
Common solutions for programming problems are called patterns/Design patterns
Les solucions que s'utilitzen de forma comuna per a resoldre problemes de programació s'anomenen patrons o patrons de disseny
Bàsicament podem categoritzar-los en tres tipus:
Resources:
Altres relacionats:
Resources:
SOLID és un acrònim de Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion introduit per Michael Feathers per fer referència als primers 5 principis definit per Robert C. Martin (aka uncle Bob) per al disseny de programari orientat a objectes.
L'objectiu d'aquest principis és aconseguir que els programes creats seguint aquests principis siguin més fàcils de mantenir i estendre en el futur. SOLID són doncs unes guies de treball que s'apliquen durant el desenvolupament de programari per tal de refactoritzar el codi fins que sigui més llegible, comprensible i extensible. És part d'una estratègia per al desenvolupament àgil i adaptatiu.
Recursos:
Una gràfica exemple de la repartició típica de responsabilitats en una aplicació:
Podeu trobar un exemple pas a pas (en anglès) at/ You could find a step by step example at:
See also SOLID principles example with Laravel section Single Responsibility Principle
Archive: Notes sobre la preparació de l'exemple Single Responsibility Principle example with Laravel
Recursos
Lema:
IMPORTANT: Software entities should be OPEN for extension but CLOSED for modification
Com?
Separate extensible behaviour behind a interface and flip de dependencies
o vegeu també el patró de disseny:
Strategy Design Pattern [1]
Exemple incorrecte:
https://github.com/acacha/solid_laravel/blob/stupid_case_s/app/InvoiceReport.php
El métode show:
public function show(){ return "<strong>" . $this->invoice->totalAmmount . " </strong>"; }
No està ni molt menys tancat a modificacions ja que per exemple l'haurem de modificar segur si volem mostrar la sortida en format text en comptes de HTML o per exemple per a una API en format XML/Json i tampoc tenim la classe preparada/oberta a extensions és a dir preparada per ampliar el seu comportament (saber mostrar no només en HTML sinó també en altre formats). La sol·lució és utilitzar interfícies i invertir les dependències:
Separate extensible behaviour behind a interface and flip de dependencies
La sol·lució:
Nou mètode show que depen d'una interfície (per exemple l'anomenem InvoiceShowInterface)
public function show(InvoiceShowInterface $i){ return $i->show($this->invoice); }
On InvoiceShowInterface:
interface InvoiceShowInterface { public function show($invoice); }
I podem tindrà múltiples implementacions, per exemple HTML:
class InvoiceShowHtml implements InvoiceShowInterface { public function show($invoice) { return "<strong>" . $invoice->totalAmmount . " </strong>"; } }
i text:
class InvoiceShowText implements InvoiceShowInterface { public function show($invoice) { return "total: " . $invoice->totalAmmount; } }
Resources:
Strategy Design Pattern fa ús del Polimorfisme/polymorphism en OOP
L'exemple:
https://laracasts.com/series/whip-monstrous-code-into-shape/episodes/9
És un molt bon exemple de com i quan identificar la possibilitat d'aplicar aquest patró
Recursos:
Vegeu Template Method Design Pattern
Recursos:
As we progress with these tutorials, we can put each new principle in the context of the already discussed ones. We already discussed the Single Responsibility (SRP) that stated that a module should have only one reason to change. If we think about OCP and SRP, we can observe that they are complementary. Code specifically designed with SRP in mind will be close to OCP principles or easy to make it respect those principles. When we have code that has a single reason to change, introducing a new feature will create a secondary reason for that change. So both SRP and OCP would be violated. In the same way, if we have code that should only change when its main function changes and should remain unchanged when a new feature is added to it, thus respecting OCP, will mostly respect SRP also.
This does not mean that SRP always leads to OCP or vice versa, but in most cases if one of them is respected, achieving the second one is quite simple.
IMPORTANT: No confondre Dependency Inversion with Dependency Injection tenen certa relació però són conceptes diferents!
El principi Dependency inversion principle es basa en:
Depends on abstractions not on concretions
és a dir:
Dependre d'abstraccions i no pas de concrecions
Normalment en programació les Abstraccions s'implementen mitjançant Interfícies i Classes abstractes i les concrecions són classes que implementen les interfícies i pot ser que heretin de classes abstractes.
I amb quin objectiu? Doncs implementar el que s'anomena:
Decoupling code o desacoblament de codi
El concepte d'spaghetti code està relacionat amb el concepte de desacoblament de codi ja que precisament el codi espagueti és un codi altament acoblat és a dir que és difícil de modificar parts específiques o components del codi sense necessitat de modificar altres components relacionats (és diu que aquest components estan altament acoblats) de la mateixa forma que no és fàcil separar un espagueti (noodle) del plat d'espagueti.
Un altre exemple interessant és el dels instruments elèctrics, el cablejat de llum i els endolls (sockets). Vegeu la transparència 32 de [2]:
Recursos:
Resources:
https://github.com/johnpapa/angular-styleguide
Sovint és un concepte relacionat amb el de Service Container, vegeu també Laravel Service Container.
Vegeu:
Frameworks:
See AngularJS and:
https://github.com/johnpapa/angular-styleguide
Vegeu Software craftsmanship