Реализация абстрактной коллекции

110
30 июня 2021, 14:30

Помогите пожалуйста реализовать абстрактный класс коллекции.

Хочется написать свой велосипед, чтобы до конца понять, как это должно работать и т.д.

Этот класс должен решить проблемы c типизацией возвращаемых значений метода.

Как я себе это представляю:

class PostCollection extends BaseCollection {
    # Устанавливаю тип коллекции, 
    # при попытке добавить в коллекцию другой тип - выбрасываем исключение
    protected static $collectionType = PostItem::class;
}
class PostItem {
   //...
}
class Posts {
   public function getAllPost() : PostCollection { ... }
}

Также, желательно, чтобы у абстрактного класса таже были реализованы интерфейсы Iterator, ArrayAccess, Countable;

Также планирую добавлять такие методы как map(), sort() и т.д.

Готовой реализации не требую. От вас нужна помощь, чтобы подсказали, как правильно нужно реализовать такие коллекции, какие нюансы стоит учесть? Правильно ли я через статическое свойство $collectionType определяю тип текущей коллекции ?

Или есть какие-то другие варианты ?

Пробовал разобрать, как устроены коллекции в laravel или других фреймворках. Было сложно и непонятно. Очень много кода, предусмотрено все, и на все случаи жизни. Еще и через рефлексию и т.д. Мне хотелось бы минимально рабочую версию реализовать.

За помощь буду очень благодарен!

Answer 1

В "минимальной рабочей версии" это должно выглядеть как то так:

abstract class BaseCollection
{
    private   $items = [];
    protected $collectionType;
    public function get(): array
    {
        return $this->items;
    }
    public function first()
    {
        return array_shift($this->items);
    }
    public function add($item): void
    {
        $this->checkItemType($item);
        $this->items[] = $item;
    }
    private function checkItemType($item)
    {
        if (get_class($item) !== $this->collectionType) {
            throw new Exception('bad type item');
        }
    }
}

class PostCollection extends BaseCollection
{
    protected $collectionType = PostItem::class;
}
class PostItem
{
    private $name;
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    public function getName(): string
    {
        return $this->name;
    }
}
class Posts
{
    public function getAllPost(): PostCollection
    {
        $collection = new PostCollection();
        $collection->add(new PostItem('first'));
        $collection->add(new PostItem('last'));
        return $collection;
    }
}

$posts = new Posts();
$collection = $posts->getAllPost();
echo $collection->first()->getName();
READ ALSO
Как правильно хранить изображения на сервере?

Как правильно хранить изображения на сервере?

Требуется загрузить изображение в MySQL через форму :

103
Получить аватар из инсты php

Получить аватар из инсты php

Как получить аватар из инстаграм? пробую так, но выдает null

114
wordpress изменить автора записи

wordpress изменить автора записи

Как изменить в wordpress автора записи если пользователь состоит в группе editorКак отобразить у него это поле?

94