Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
SOLID principi PHP
Jānis Mozgis
Printful
SOLID… kas pie velna tas ir?
S - Single Responsibility
O - Open-Closed
L - Liskov Substitution
O - Interface Segregation
D...
Single Responsibility
“A class should have only one reason to be”
Single Responsibility
“A class should have only one reason to change”
Single Responsibility
class UserRegistrationController
{
public function register(Request $request, Response $response) {
...
Single Responsibility
class UserRegistrationService {
public function __construct(UserRepo $repo, MailService $emailServic...
Open-Closed
“Entities should be open for extension, but closed for modification.”
Open-Closed
class Order {
public function calculateTotal() {
foreach ($this->products as $product) {
$this->total += $prou...
Open-Closed
class Order
{
public function calculateTotal() {
foreach ($this->products as $product) {
if ($procut->type == ...
Open-Closed
class Order
{
public function calculateTotal() {
foreach ($this->products as $product) {
if ($procut->type == ...
Open-Closed
class Order {
public function calculateTotal() {
foreach ($this->products as $product) {
$total += $product->c...
Open-Closed
class DiditalProduct implements ProductPriceCalculation
{
public function calculateTotal(): float
{
return $th...
Open-Closed
class NormalProduct implements ProductPriceCalculation
{
public function calculateTotal(): float
{
return $thi...
Liskov Substitution
“Let q(x) be a property provable about objects of x of type T. Then
q(y) should be provable for object...
Liskov Substitution
“Any implementation of an abstraction should be substitutable in
any place that the abstraction is acc...
Liskov Substitution
class Rectangle
{
protected $width;
protected $height;
public function setHeight($height) { $this->hei...
Liskov Substitution
class Square extends Rectangle
{
public function setHeight($value) {
$this->width = $value;
$this->hei...
Liskov Substitution
class RectangleTest
{
private $rectangle;
public function __construct(Rectangle $rectangle)
{
$this->r...
Interface Segregation
“A client should never be forced to implement an interface that it
doesn't use or clients shouldn't ...
Interface Segregation
interface ShapeInterface {
public function calculateArea(): float;
public function calculateVolume()...
Interface Segregation
interface AreaCalculationInterface
{
public function calculateArea(): float;
}
interface VolumeCalcu...
Interface Segregation
class Cube implements AreaCalculationInterface, VolumeCalculationInterface
{
$this->height;
public f...
Dependency Inversion
“Entities must depend on abstractions not on concretions.
High level module must not depend on the lo...
Dependency Inversion
class PasswordReminder {
private $dbConnection;
public function __construct(MySQLConnection $dbConnec...
Dependency Inversion
interface DBConnectionInterface {
public function connect();
}
class MySQLConnection implements DBCon...
SOLID - pros and cons
Pros:
● Izmaiņas kādā applikācijas daļā nesalauzīs
citu daļu;
● Kods ir fleksiblāks koda izmaiņām;
●...
?
“SOLID principles in PHP – how to apply them in PHP and why should we care“ by Jānis Mozgis from Printful Latvia at Modern...
“SOLID principles in PHP – how to apply them in PHP and why should we care“ by Jānis Mozgis from Printful Latvia at Modern...
Upcoming SlideShare
Loading in …5
×

“SOLID principles in PHP – how to apply them in PHP and why should we care“ by Jānis Mozgis from Printful Latvia at Modern PHP focused 66th DevClub.lv

1,642 views

Published on

Jānis is senior software developer at Printful Latvia.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

“SOLID principles in PHP – how to apply them in PHP and why should we care“ by Jānis Mozgis from Printful Latvia at Modern PHP focused 66th DevClub.lv

  1. 1. SOLID principi PHP Jānis Mozgis Printful
  2. 2. SOLID… kas pie velna tas ir? S - Single Responsibility O - Open-Closed L - Liskov Substitution O - Interface Segregation D - Dependency Inversion
  3. 3. Single Responsibility “A class should have only one reason to be”
  4. 4. Single Responsibility “A class should have only one reason to change”
  5. 5. Single Responsibility class UserRegistrationController { public function register(Request $request, Response $response) { $data = $request->get('data'); $validation = new UserRegistrationValidation($data); if ($validation->isValid()) { $user = DB::insert("INSERT INTO...", $data); $mail = CustomMailClient::to($user->email) ->sublect('Some cool email title') ->tempalte('registration') ->with($data)->send(); $response->view('registration_completed')->with($data); } } }
  6. 6. Single Responsibility class UserRegistrationService { public function __construct(UserRepo $repo, MailService $emailService, UserValidator $validator){ $this->repo = $repo; $this->emailService = $emailSerice; $this->validator = $validator; } public function register(array $data): bool { if ($this->validator($data)) { $user = $this->repo->addUser($data); $this->emailService->sendRegistrationEmail($user); return true; } return false; }
  7. 7. Open-Closed “Entities should be open for extension, but closed for modification.”
  8. 8. Open-Closed class Order { public function calculateTotal() { foreach ($this->products as $product) { $this->total += $prouct->calculatePrice() + $product->calculateShipping(); } } public function addProduct(Product $product) { $this->products[] = $product; } } class Product { public function calculatePrice() { // … } public function calculateShipping() { // … } }
  9. 9. Open-Closed class Order { public function calculateTotal() { foreach ($this->products as $product) { if ($procut->type == 'digital') { $this->total += $prouct->calculatePrice(); } else { $this->total += $prouct->calculatePrice() + $product->calculateShipping(); } } } }
  10. 10. Open-Closed class Order { public function calculateTotal() { foreach ($this->products as $product) { if ($procut->type == 'digital') { $this->total += $prouct->calculatePrice(); } elseif ($procut->type == 'sample') { $this->total += $prouct->calculateShipping(); } else { $this->total += $prouct->calculatePrice() + $product->calculateShipping(); } } } }
  11. 11. Open-Closed class Order { public function calculateTotal() { foreach ($this->products as $product) { $total += $product->calculateTotal(); } } public function addProduct(ProductPriceCalculation $product) { $this->products[] = $product; } } interface ProductPriceCalculation { public function calculateTotal(): float; }
  12. 12. Open-Closed class DiditalProduct implements ProductPriceCalculation { public function calculateTotal(): float { return $this->calculatePrice(); } } class SamplelProduct implements ProductPriceCalculation { public function calculateTotal(): float { return $this->calculateShipping(); } }
  13. 13. Open-Closed class NormalProduct implements ProductPriceCalculation { public function calculateTotal(): float { return $this->calculateShipping() + $this->calculatePrice(); } }
  14. 14. Liskov Substitution “Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T..”
  15. 15. Liskov Substitution “Any implementation of an abstraction should be substitutable in any place that the abstraction is accepted”
  16. 16. Liskov Substitution class Rectangle { protected $width; protected $height; public function setHeight($height) { $this->height = $height; } public function getHeight() { return $this->height; } public function setWidth($width) { $this->width = $width; } public function getWidth() { return $this->width; } public function area() { return $this->height * $this->width; } }
  17. 17. Liskov Substitution class Square extends Rectangle { public function setHeight($value) { $this->width = $value; $this->height = $value; } public function setWidth($value) { $this->width = $value; $this->height = $value; } }
  18. 18. Liskov Substitution class RectangleTest { private $rectangle; public function __construct(Rectangle $rectangle) { $this->rectangle = $rectangle; } public function testArea() { $this->rectangle->setHeight(2); $this->rectangle->setWidth(3); // Expect rectangle's area to be 6 } }
  19. 19. Interface Segregation “A client should never be forced to implement an interface that it doesn't use or clients shouldn't be forced to depend on methods they do not use.”
  20. 20. Interface Segregation interface ShapeInterface { public function calculateArea(): float; public function calculateVolume(): float; } Class Cube implements ShapeInterface { $this->height; public function calculateArea() { return pow($this->height, 2); } public function calculateVolume() { return pow($this->height, 3); } } class Square implements ShapeInterface { $this->height; public function calculateArea() { return pow($this->height, 2); } public function calculateVolume() { /* do nothing? */ } }
  21. 21. Interface Segregation interface AreaCalculationInterface { public function calculateArea(): float; } interface VolumeCalculationInterface { public function calculateVolume(): float; }
  22. 22. Interface Segregation class Cube implements AreaCalculationInterface, VolumeCalculationInterface { $this->height; public function calculateArea() { return pow($this->height, 2); } public function calculateVolume() { return pow($this->height, 3); } } class Square implements AreaCalculationInterface { $this->height; public function calculateArea() { return pow($this->height, 2); } }
  23. 23. Dependency Inversion “Entities must depend on abstractions not on concretions. High level module must not depend on the low level module, but they should depend on abstractions.” ”
  24. 24. Dependency Inversion class PasswordReminder { private $dbConnection; public function __construct(MySQLConnection $dbConnection) { $this->dbConnection = $dbConnection; // send out reminder logic } }
  25. 25. Dependency Inversion interface DBConnectionInterface { public function connect(); } class MySQLConnection implements DBConnectionInterface { public function connect() { // connection logic } } class PasswordReminder { private $dbConnection; public function __construct(DBConnectionInterface $dbConnection) { $this->dbConnection = $dbConnection; // send out reminder logic } }
  26. 26. SOLID - pros and cons Pros: ● Izmaiņas kādā applikācijas daļā nesalauzīs citu daļu; ● Kods ir fleksiblāks koda izmaiņām; ● Applikācijas daļas ir vieglāk testējamas; Cons ● Jāraksta nedaudz vairāk koda ● Applikācija var izaugt daudz mazos moduļos līdz ar to ir grūtāk orientēties; ● Reālā dzīvē bieži ir grūti paredzēt, kur izmantot šos principus un kur nē.
  27. 27. ?

×