oop — динамически реализовать интерфейс на основе значения свойства объекта в PHP?

Допустим, у нас есть Dog класс и Category класс, к которому могут быть отнесены собаки.

class Dog {
function categories() {} // Return the categories of the dog.
}

class Category {
function dogs() {} // Return the dogs under this category.
}

Собаки могут иметь категории «домашнее животное» и «овчарка». При присвоении категории «домашнее животное» это «домашняя собака», и то же самое относится и к «пастуху».

Собаки и овчарки имеют разные атрибуты и функции. Однако собака может быть как «собакой», так и «овчаркой».

Я могу представить себе разные интерфейсы для «любимой собаки» и «овчарки», например

interface Huggable {
function hug()
}

interface Trainable {
function train()
}

В идеале, когда собака относится к категории «домашние животные», она реализует Huggable интерфейс, если он относится к категории «пастух», он реализует Trainable категория.

Является ли это возможным?

-1

Решение

Как я уже говорил, это невозможно реализовать с помощью PHP.

Но вы можете реализовать что-то, например, с помощью декораторов.

Глупый декоратор подход:

У вас будет класс, который будет украшен:

class Animal {

protected $categories = [];

public function getCategories() {
return $this->categories;
}

public function addCategory( string $category ) {
// we should check the animal doesn't already belong to this category
$this->categories[] = $category;

}
}

Ваши интерфейсы, Trainable а также Huggable:

interface Trainable {

function train();
}

interface Huggable {
// see https://github.com/php-fig/fig-standards/blob/master/proposed/psr-8-hug/psr-8-hug.md
function hug() : bool;
}

Один декоратор, который реализует Trainable и добавляет конкретную категорию к оформленному экземпляру:

class PetDecorator extends Animal implements Trainable {


public function __construct( Animal $animal ) {

$this->categories = $animal->getCategories();
$this->addCategory('pet');

}

public function train() {
echo "I'm housebroken!\n";
}
}

И другой FluffyDecorator который реализует Huggable

class FluffyDecorator extends Animal implements Huggable {

public function __construct( Animal $animal ) {

$this->categories = $animal->getCategories();
$this->addCategory('loveBear');
}

public function hug( ) :bool {
echo "Much hug!\n";
return true;
}
}

Наконец, вы бы использовали это так:

$fido    = new Animal();
$fidoPet = new PetDecorator($fido);

$fidoPet->train();
// I'm housebroken!

print_r($fidoPet->getCategories());
/*
Array
(
[0] => pet
)
*/

$fidoLove = new FluffyDecorator($fidoPet);
// Much hug!
$fidoLove->hug();

print_r($fidoLove->getCategories());
/*
Array
(
[0] => pet
[1] => loveBear
)
*/

Отношения «многие ко многим» между «Собаками» и «Категориями» я оставляю на ваше усмотрение. Это отдельная проблема и может быть решена различными способами.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]