Skip to content

Commit c8905c1

Browse files
committed
solid
1 parent c86c7cb commit c8905c1

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

architecture/solid.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
## SOLID принципы
2+
3+
Из SOLID понадобиться всего один принцип Dependency Inversion и его реализация dependency injection, который поможет обеспечить Low Coupling.
4+
5+
Dependency Inversion (Принцип инверсии зависимостей) главная цель данного принципа уменьшить зацепление классов между собой.
6+
7+
```php
8+
interface FileContract {
9+
public function getDocumentBody(): string;
10+
}
11+
12+
class Bill implements FileContract {
13+
public function getDocumentBody(): string
14+
{
15+
...
16+
return "Bill sum";
17+
}
18+
}
19+
20+
class Report implements FileContract {
21+
public function getDocumentBody(): string
22+
{
23+
...
24+
return "Report data";
25+
}
26+
}
27+
28+
class Printer {
29+
public function execute(FileContract $file)
30+
{
31+
// логика печати
32+
}
33+
}
34+
35+
class PrintBill {
36+
public function execute()
37+
{
38+
$printer = new Printer();
39+
40+
$bill = new Bill();
41+
$printer->execute($bill);
42+
}
43+
}
44+
45+
class PrintReport {
46+
public function execute()
47+
{
48+
$printer = new Printer();
49+
50+
$report = new Report();
51+
$printer->execute($report);
52+
}
53+
}
54+
55+
```
56+
Класс `Printer` зависит от контракта `FileContract`, который нужно реализовать. Такой подход позволяет использовать класс `Printer` для печати чего угодно.
57+
Единственная проблема. Предположим что класс `Printer` будет у себя в конструкторе принимать еще какой-то объект в конструкторе допустим `PrinterSettings`.
58+
Тогда получается что `PrintReport` и `PrintBill` будут зависеть от класса `PrinterSettings` хотя кроме как для настройки `Printer` он применяться не будет.
59+
60+
Обратимся к инструменту, который решит проблему с зависимостями. Убрать эту лишнюю зависимость можно при помощи Dependency injection которая обеспечивает инверсию управления из ООП принципов.
61+
Dependency injection при помощи абстракции один раз настроив класс его можно использовать в других реализациях, не затягивая лишние зависимости класса.
62+
Примеры реализации есть в вендорном пакете [php di](https://github.com/PHP-DI/PHP-DI), [symfony](https://symfony.com/doc/current/components/dependency_injection.html) и [laravel](https://laravel.com/docs/8.x/providers)
63+
64+
```php
65+
class PrintReport {
66+
private Printer $printer;
67+
68+
public function __construct(Printer $printer)
69+
{
70+
$this->printer = $printer;
71+
}
72+
public function execute()
73+
{
74+
$report = new Report();
75+
$this->printer->execute($report);
76+
}
77+
}
78+
79+
$printReport = $container->get(PrintReport::class);
80+
$printReport->execute();
81+
```
82+
83+
Переменная `$container` инициализируется в ядре и глобальна по всему приложению. Исполняется фасадом/синглтоном или иными способами.
84+
В laravel это функция `app()`, в symfony класс `ContainerBuilder` отвечает за получение настроенного объекта;

readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@
2626
- [Функциональное программирование](./architecture/functional-programming.md)
2727
- [Объектно-ориентированное программирование](./architecture/oop.md)
2828
- Куда писать код? Структуризация проекта
29-
- [GRASP](./architecture/grasp.md)
29+
- [GRASP](./architecture/grasp.md)
30+
- [SOLID](./architecture/solid.md)

0 commit comments

Comments
 (0)