T
T
tester_toster2018-04-03 12:20:18
PHP
tester_toster, 2018-04-03 12:20:18

How to correctly implement the architecture for related objects with a service, collection and repository?

Good afternoon.
There is a table in the database, the entity is stored in it: Post.
By itself, this entity is not used, depending on some rows in the table, a child entity is created News, Article, etc., which have the same methods, but may have additional different methods.
I would like to implement all this with repositories and interfaces so that you can change it if necessary
. I sketched an example so that it was at least a little clear what I want:

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();
    }
}

How to implement all this correctly?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
DeFacto, 2018-04-12
@tester_toster

went deep into abstraction.
1. Who will use the getTags(), getCountry() methods and for what?
logically, let's say that your ArticleContract interface adds the getTags() function,
then it's better to create the TagsContract interface,
since then the requirements may change, and tags will be needed for News
2. Why make interfaces for every sneeze? For Service, I don't see the point at all. Or are you going to replace ArticleService somewhere with another ArticelService which should also return an ArticleCollectionContract?
3. the easiest option for starters ,
leave the interface PostContract
as necessary for the functionality, make the interface TagContract
leave the PostRepostory, PostService
We extend PostRepostory so that it can return objects by type (for example
, $postRepostory->getNews(), $postRepostory->getArticles() )
In those places where you really need additional functionality of the getCountry type, you create a separate interface CountryContact
and further in those places where there will be a dependency embedding CountryContact
as a result class News extends Post implements CountryContact, TagContract

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question