Академический Документы
Профессиональный Документы
Культура Документы
Урок 2
Принципы
проектирования
UML
На уроке разберём
+ Публичный (Public)
- Приватный (Private)
# Защищённый (Protected)
~ Пакет (Package)
Виды отношений
Название Графический вид Описание
Агрегация Разновидность ассоциации при отношении между целым и его частями. Встречается,
когда один класс является коллекцией или контейнером других.
Композиция Более строгий вариант агрегации. Имеет жёсткую зависимость времени существования
экземпляров класса контейнера и экземпляров содержащихся классов. Если контейнер
будет уничтожен, то всё его содержимое будет также уничтожено.
Обобщение / Показывает, что один из двух связанных классов (подтип) является частной формой
наследование другого (надтипа), который называется обобщением первого.
class Person
{
protected $name;
}
Зависимость
<?php
class Menu
{
public $nameMenu = [];
class ItemMenu
{
public $href;
public $title;
interface Transport
{
public function drive();
public function beep();
}
}
Диаграмма последовательностей
Разработчики постоянно решают
одни и те же задачи проектирования
Для многих проектировочных
задач уже найдено хорошее
решение, которое можно
применить!
Шаблон ≠ готовый код
«Не повторяйся»
Keep it super simple
«Не усложняй»
Принципы SOLID
1. Принцип единственной ответственности
(The Single Responsibility Principle)
2. Принцип открытости / закрытости
(The Open Closed Principle)
3. Принцип подстановки Барбары Лисков
(The Liskov Substitution Principle)
4. Принцип разделения интерфейса
(The Interface Segregation Principle)
5. Принцип инверсии зависимостей
(The Dependency Inversion Principle)
Принцип единственной ответственности
”
Принцип единственной ответственности
class Basket
{
class Basket public function getItems() {/**/}
{ public function getTotalCount() {/**/}
public function getItems() {/**/} public function getTotalPrice() {/**/}
public function
public function
public function
getTotalCount() {/**/}
getTotalPrice() {/**/}
save() {/**/}
→ }
class BasketRepository
public function update() {/**/} {
public function clear() {/**/} public function save() {/**/}
} public function update() {/**/}
public function clear() {/**/}
}
Принцип открытости / закрытости
return $total;
}
}
Принцип открытости / закрытости
abstract class Basket
{
public function getTotalPrice()
{
$products = $this->getProducts();
$discount = $this->getDiscount();
”
Принцип подстановки Барбары Лисков
class Rectangle
{
class Square extends Rectangle
protected $width;
{
protected $height;
public function setWidth(int $width): void
{
public function setWidth(int $width): void
parent::setWidth($width);
{ $this->width = $width; }
parent::setHeight($width);
Прямоугольник } Квадрат
public function setHeight(int $height): void
{ $this->height = $height; } public function setHeight(int $height): void
{
public function getWidth(): int parent::setHeight($height);
{ return $this->width; } parent::setWidth($height);
}
public function getHeight(): int }
{ return $this->height; }
}
Принцип подстановки Барбары Лисков
public function getSquare(Rectangle $rectangle, int $width, int $height): int
{
$rectangle->setWidth($width);
$rectangle->setHeight($height);
“ Множество специализированных
интерфейсов лучше, чем один
универсальный
”
Принцип разделения интерфейсов
/* Общий интерфейс для товаров */
interface IItem
{
public function setCondition();
public function setPrice();
}
interface IItem
{ /* Интерфейс для одежды */
public function setSize();
→
interface IWearable
public function setCondition(); {
public function setMaterial(); public function setMaterial();
public function setBestBeforeDate(); public function setSize();
public function setPrice(); }
}
/* Интерфейс для портящихся товаров */
interface IDegradable
{
public function setBestBeforeDate();
}
Принцип разделения интерфейсов
/* Рубашка */
class Shirt implements IItem, IWearable
{
public function setSize() {/**/}
public function setCondition() {/**/}
public function setMaterial() {/**/}
public function setPrice() {/**/}
}
/* Томатный суп */
class TomatoSoup implements IItem, IDegradable
{
public function setCondition() {/**/}
public function setPrice() {/**/}
public function setBestBeforeDate() {/**/}
}
Принцип инверсии зависимостей
”
Принцип инверсии зависимостей
class Basket
{
public function getTotalPrice(): float
{
$total = 0;
foreach ($this->items as $item) {
$total += $item->getPrice();
}
return $total;
}
}
Принцип инверсии зависимостей
interface IDiscountProvider
{
public function isActivatedByUser(User $user);
public function getDiscount(User $user);
}
● через конструктор;
● через метод-сеттер;
● через публичное свойство.
Внедрение зависимости через
конструктор
class Basket
{
protected $discountProvider;
{
public function __construct(IDiscountProvider $discountProvider)
Подходит для
$this->discountProvider = $discountProvider; зависимостей, без
}
}
которых никак
Внедрение зависимости через метод-
сеттер
class Basket
{
protected $discountProvider;
class Basket
{
public $discountProvider;
}
Так делать не стоит,
/* Внешний обработчик */
$basket = new Basket();
особенно в PHP до
$basket->discountProvider = new PromoCodeProvider(); версии 7.4
Принципы GRASP
Craig Larman
Принципы GRASP