Čtvrtkon #53 - Štěpán zikmund
TRANSCRIPT
![Page 1: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/1.jpg)
SOLID | Štěpán Zikmund
![Page 2: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/2.jpg)
![Page 3: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/3.jpg)
krása
![Page 4: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/4.jpg)
• změny v zadání
• nové funkce, které jsou v rozporu s původní funkcionalitou
• deadliny
Co by mohly být takový překážky..
![Page 5: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/5.jpg)
no, mohly by…
![Page 6: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/6.jpg)
source code
![Page 7: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/7.jpg)
💩
![Page 8: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/8.jpg)
Rigidity
![Page 9: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/9.jpg)
Fragilitiy
![Page 10: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/10.jpg)
Imobility
![Page 11: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/11.jpg)
Coupling? How?
![Page 12: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/12.jpg)
OOP
![Page 13: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/13.jpg)
![Page 14: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/14.jpg)
SOLID
![Page 15: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/15.jpg)
Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
![Page 16: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/16.jpg)
– Uncle Bob
„OOP is about managing dependency by selectively inverted some key dependencies in your architecture to prevent rigidity, fragility, not
reusability“
![Page 17: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/17.jpg)
The Dependency Inversion Principle
Depend on abstractions, not on concretions
![Page 18: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/18.jpg)
m
n
![Page 19: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/19.jpg)
m n
![Page 20: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/20.jpg)
m interface
n
![Page 21: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/21.jpg)
class Authentication { private $userProvider;
public function __construct(UserProvider $userProvider) { $this->userProvider = $userProvider; } }
![Page 22: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/22.jpg)
class Authentication { private $userProvider;
public function __construct(UserProviderInterface $userProvider) { $this->userProvider = $userProvider; } }
![Page 23: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/23.jpg)
The Single Responsibility Principle
A class should have one, and only one, reason to change
![Page 24: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/24.jpg)
Symptomy
• účel třídy nejde pospat bez spojek a, nebo
• třída obsahuje velké množství properties a public method
• třída obsahuje velké množství závislostí na další objekty
![Page 25: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/25.jpg)
Řešení
• kompozice
• event listener
• …
![Page 26: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/26.jpg)
Employee
+ getSalary() + getName() + setSalary() + setName() + getSalaryReport()
![Page 27: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/27.jpg)
Employee
+ getSalary() + getName() + setSalary() + setName()
SalaryReportBuilder
+ getReport(Employee $employee)
![Page 28: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/28.jpg)
The Open Closed Principle
You should be able to extend a classes behaviour, without modifying it
![Page 29: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/29.jpg)
Pro přidání nové featury nechcete editovat stávající
kód, ale vytvořit nový
![Page 30: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/30.jpg)
function doSomething($howToDoIt) { if ($howToDoIt == 'something') { return someBehaviour(); } else if ($howToDoIt == 'somethingOther') { return someOtherBehaviour(); } else { throw new \IllegalArgumentException(); } }
![Page 31: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/31.jpg)
Symptomy
• switch statement
• třída zná více různých service se stejným interfacem nebo s podobným účelem
![Page 32: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/32.jpg)
Employee
+ getSalary() + getName() + setSalary() + setName()
SalaryReportBuilder
+ getXmlReport(Employee $employee) + getJsonReport(Employee $employee)
![Page 33: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/33.jpg)
Employee
+ getSalary() + getName() + setSalary() + setName()
SalaryReportBuilder
+ getXmlReport(Employee $employee) + getJsonReport(Employee $employee)SRP
![Page 34: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/34.jpg)
XmlReportBuilder
+ getXmlReport(..)
SalaryReportBuilder
+ getReport($type)
JsonReportBuilder
+ getJsonReport(..)
![Page 35: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/35.jpg)
function getReport($type, $employee) { switch ($type): case 'xml' return $this->xmlReportBuilder->getReport($employee); case 'json' return $this->jsonReportBuilder->getReport($employee); default: throw new \IllegalArgumentException(); }
![Page 36: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/36.jpg)
function getReport($type, $employee) { switch ($type): case 'xml' return $this->xmlReportBuilder->getReport($employee); case 'json' return $this->jsonReportBuilder->getReport($employee); default: throw new \IllegalArgumentException(); } OCP
![Page 37: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/37.jpg)
XmlReportBuilder
+ getReport(..) + getName()
SalaryReportBuilder
+ addBuilder(ReportInterface) + getReport($type)
ReportBuilderInterface
+ getReport(..) + getName
JsonReportBuilder
+ getReport(..) + getName()
![Page 38: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/38.jpg)
function getReport($type, $employee) { foraech ($this->reportBuilders as $builder) { if ($builder->getName() == $type) { return $builder->getReport($employee); } }
throw new \IllegalArgumentException(); }
![Page 39: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/39.jpg)
The Liskov Substitution Principle
Derived classes must be substitutable for their base classes.
![Page 40: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/40.jpg)
app rectangle
![Page 41: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/41.jpg)
app rectangle
square
![Page 42: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/42.jpg)
class Square { public function setHeight($height) { $this->height = $height; parent::setWidth($height); } public function setWidth($width) { $this->width = $width; parent::setHeight($width); } }
![Page 43: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/43.jpg)
if ($rectangle instanceof Square) { //.. } else { //.. }
![Page 44: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/44.jpg)
app rectangle
square
![Page 45: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/45.jpg)
OOP není modelování skutečného světa, ale
jeho reprezentací
![Page 46: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/46.jpg)
class Rectangle { public function getHeight() {} public function getWidth() {} public function setHeight() {} public function setWidth() {} }
class Square { public function getSize() {} public function setSize() {} }
![Page 47: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/47.jpg)
The Interface Segregation Principle
Make fine grained interfaces that are client specific
![Page 48: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/48.jpg)
m interface
n
Client specific?
![Page 49: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/49.jpg)
m interface
n
![Page 50: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/50.jpg)
Fine grained?
interface FileInterface { public function changeName() public function changeOwner() }
![Page 51: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/51.jpg)
class DropboxFile implements FileInterface { public function changeName() { } public function changeOwner() { // don’t need this method } }
![Page 52: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/52.jpg)
interface FileInterface { public function changeName() }
interface SupportsChangeOfOwnershipInterface { public function changeOwner() }
![Page 53: Čtvrtkon #53 - Štěpán Zikmund](https://reader031.vdocuments.mx/reader031/viewer/2022021507/58b88bfd1a28ab3e3a8b4b0b/html5/thumbnails/53.jpg)
SRP OCP LSP ISP DIP