Как правильно реализовать архитектуру для связанных объектов с сервисом, коллекцией и репозиторием? Добрый день.
Есть таблица в бд, в ней хранится сущность: Post.
Сама по себе эта сущность не используется, в зависимости от некоторых строк в таблице, создается дочерняя сущность News, Article и.т.д, у которых есть одинаковые методы, но могут быть дополнительные разные методы.
Хотелось бы реализовать все это с репозиториями и интерфейсами, чтобы можно было менять при необходимости
Набросал пример, чтобы было хоть немного понятно, чего я хочу:interface PostContract
{
public function getId();
public function getTitle();
}
interface NewsContract extends PostContract
{
public function getCountry();
}
interface ArticleContract extends PostContract
{
public function getTags();
}
abstract class Post implements PostContract
{
public function getId()
{
}
public function getTitle()
{
}
}
class News extends Post implements NewsContract
{
public function getCountry()
{
}
}
class Article extends Post implements ArticleContract
{
public function getTags()
{
}
}
interface NewsCollectionContract
{
public function push(NewsContract $item);
}
interface ArticleCollectionContract
{
public function push(ArticleContract $item);
}
class NewsCollection implements NewsCollectionContract
{
public function push(PostContract $item)
{
}
}
class ArticleCollection implements ArticleCollectionContract
{
public function push(ArticleContract $item)
{
}
}
interface PostRepositryContract
{
public function getList();
}
interface NewsRepositryContract extends PostRepositryContract
{
public function getList() : NewsCollectionContract;
public function get($id) : NewsContract;
}
interface ArticleRepositryContract extends PostRepositryContract
{
public function getList() : ArticleCollectionContract;
public function get($id) : ArticleContract;
}
abstract class PostRepositry
{
// Общие методы
}
class NewsRepository extends PostRepository implements NewsRepositryContract
{
public function getList() : NewsCollectionContract
{
return new NewsCollection;
}
public function get($id) : NewsContract
{
return new News;
}
}
class ArticleRepositry extends PostRepository implements PostRepositryContract
{
public function getList() : ArticleCollectionContract
{
new ArticleCollection;
}
public function get($id) : ArticleContract
{
new Article;
}
}
interface NewsServiceContract
{
public function getList(array $params) : NewsCollectionContract;
}
interface ArticleServiceContract
{
public function getList(array $params) : ArticleCollectionContract;
}
class NewsService implements NewsServiceContract
{
private $repo;
public function __construct(NewsRepositryContract $repo)
{
$this->repo = $repo;
}
public function getList(array $params) : NewsCollectionContract
{
return $this->repo->getList();
}
}
class ArticleService implements ArticleServiceContract
{
private $repo;
public function __construct(ArticleRepositryContract $repo)
{
$this->repo = $repo;
}
public function getList(array $params) : ArticleCollectionContract
{
return $this->repo->getList();
}
}
Как все это реализовать правильно?

21 Авг 2019 в 07:00
154 +1
0
Ответы
1

У вас уже весьма неплохой набросок архитектуры для связанных объектов с сервисом, коллекцией и репозиторием. Однако, есть несколько моментов, которые стоит улучшить или обратить внимание:

Применение интерфейсов на уровне сервисов (NewsServiceContract, ArticleServiceContract) дает возможность легко подменять репозитории или сами сервисы в будущем. Таким образом, соблюдается принцип инверсии зависимостей (Dependency Inversion Principle).Нет необходимости вводить различные коллекции (NewsCollection, ArticleCollection). Вы можете использовать одну универсальную коллекцию и передавать в неё разные типы объектов. Например, можно создать общий класс PostCollection и передавать в него объекты News или Article.При объявлении методов get() в репозиториях NewsRepository и ArticleRepository, следует вернуть результат операции, например, return new News(); вместо простого создания объекта.Разумно обрабатывать ошибки, например, проверкой на существование объекта перед его возвратом из репозитория.

Кроме того, стоит также уделить внимание названиям классов (например, PostRepository вместо PostRepositry) и также пересмотреть методы, возвращающие коллекции (getList()) в репозиториях, возможно, они могут быть модифицированы для работы с параметрами.

В целом, ваш подход к созданию архитектуры с использованием интерфейсов, абстрактных классов и разделением ответственностей сервисов, репозиториев и коллекций вполне правильный и позволит легко расширить функционал и поддерживать проект в будущем.

20 Апр в 13:10
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 83 913 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир