Давайте представим, что вы работаете в коммерции и получил реализовать следующие функции:
На экране стойки, пользователь должен иметь возможность добавлять более одной единицы товара уже присутствует, а также изменить его цвет.
Решение интуитивно понятное в данном контексте, может быть создать новый объект, продукт и установить все атрибуты равны оригинальный продукт. Но это, кажется, очень подробный, и вам нужно знать все внутренние работы класса продукта, который, кажется, сломать корпус.
Prototype-спасателей!
Сделайте рефакторинг.гуру :
Экспериментальный-это шаблон проектирования, порождающие, что позволяет копировать существующие объекты, не делая ваш код становится зависимым от своих классов.
Это означает, что вам не нужно использовать оператор new не беспокоиться о том, как настроить экземпляр скопирована идеально. Просто нужно использовать оператор клон и PHP будет решать все в одиночку.
Пример приложения
Окончательный код узел Github :
fabiothiroki/php-дизайн-шаблоны
Коллекция шаблонов проектирования, написанных на PHP
Класс Cart - не является частью проекта по умолчанию, но присутствует здесь только в том, чтобы продемонстрировать, как по умолчанию будет вписываться в реальном приложении:
final class Cart
{
/**
* @var ProductPrototype[]
*/
private array $products;
public function addProduct(ProductPrototype $product): void
{
$this->products[] = $product;
}
/**
* @return ProductPrototype[]
*/
public function getProducts(): array
{
return $this->products;
}
}
Как мы можем наблюдать, мы можем добавить новый продукт и проверить, какие продукты уже добавлены.
abstract class ProductPrototype
{
protected int $id;
protected string $name;
protected string $color;
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function getColor(): string
{
return $this->color;
}
public function setColor(string $color): void
{
$this->color = $color;
}
}
PHP уже реализует Prototype изначально, потому что любой объект уже принимает оператор клон по умолчанию. В этом примере я создал класс, ProductPrototype только для иллюстрации, реальный случай: для класса Cart - не имеет значения, какой конкретный продукт будет добавлена, при условии, что имеет атрибуты, id , name и color .
Только, чтобы упростить этот пример, я покажу два вида продукта: Смартфон и Laptop :
final class Smartphone extends ProductPrototype
{
public function __construct()
{
$this->id = 1;
$this->name = 'Smartphone';
$this->color = 'Default color';
}
}
final class Laptop extends ProductPrototype
{
public function __construct()
{
$this->id = 2;
$this->name = 'Smartphone';
$this->color = 'Default color';
}
}
Объясняя Prototype с модульного тестирования
Оператор клон на самом деле делает? Он копирует экземпляр с теми же атрибутами. Итак, в нашем примере, продукт клонировали будет иметь те же значения, id , имя цвет исходного объекта.
public function testSmartphoneClone(): void
{
$smartphone = new Smartphone();
$clonedSmartphone = clone $smartphone;
self::assertEquals($clonedSmartphone->getId(), $smartphone->getId());
self::assertEquals($clonedSmartphone->getName(), $smartphone->getName());
self::assertEquals($clonedSmartphone->getColor(), $smartphone->getColor());
self::assertEquals($clonedSmartphone, $smartphone);
self::assertNotSame($clonedSmartphone, $smartphone);
}
Как мы можем наблюдать, если бы нам пришлось клонировать объект вручную, нужно было бы знать все свойства, которые требуется скопировать, и как setá их.
Обратите внимание, что этот тест не должен быть написан в реальном приложении, потому что мы можем предположить, что оператор | клон| работает должным образом, так, что, предоставленный сам PHP.
Обратно в нашем случае использования,
Мы можем, наконец, дать Cart - возможность увеличить объем существующего продукта и изменить его цвет. Cart будет еще более счастлив, потому что не нужно беспокоиться, если будете получать экземпляр Laptop или Смартфон .
Это только использовать оператор клон и добавить товар недавно клонирован:
public function testCartCanAddClonedProducts(): void
{
$laptop = new Laptop();
$cart = new Cart();
$cart->addProduct($laptop);
$clonedLaptop = clone $laptop;
$clonedLaptop->setColor('White');
$cart->addProduct($clonedLaptop);
self::assertCount(2, $cart->getProducts());
self::assertEquals($cart->getProducts()[1]->getId(), $cart->getProducts()[0]->getId());
self::assertEquals($cart->getProducts()[1]->getName(), $cart->getProducts()[0]->getName());
self::assertEquals('White', $cart->getProducts()[1]->getColor());
self::assertEquals('Default color', $cart->getProducts()[0]->getColor());
}
Спасибо за чтение до здесь, я надеюсь, что вы поняли, что лучше на шаблон дизайна и не забудьте использовать его, когда это необходимо!
Оригинал: “https://dev.to/portugues/padrao-de-projeto-prototype-em-php-38km”