Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Architecture question #1

Open
parijke opened this issue Jun 27, 2020 · 6 comments
Open

Architecture question #1

parijke opened this issue Jun 27, 2020 · 6 comments

Comments

@parijke
Copy link

parijke commented Jun 27, 2020

Hi Marek,

Enjoyed your session last weel. Like te principles you demonstrate. I was wondering if you are willing to think with me how to use the composition over inheriting principle.

I need several entities to be commentable (containing comments) that need to be able to rollup. I am thinking about the Class Table Inheritance mapping , but I wonder if you can get this to be implemented using interfaces over inheritence?

Sorry for asking here

@mareg
Copy link
Owner

mareg commented Jul 1, 2020

Hey @parijke

This is an interesting question and I don't think I can give you a good answer knowing little about your domain.

I haven't used Class Table Inheritance Mapping myself, but from what I can see Doctrine expects the inheritance. Remember, it's not always bad to use inheritance - in some circumstances it may save you repeating your code.

Something similar I've done with the TrainType - shared, boring code is in AbstractTrainType which implements TrainType interface, then I've created a class for each train type to contain type specific logic.

Inheritance might not be a right solution though - imagine later in your project you may want to add polls to your entities, you would need to inherit from commentable entities.

My question would be - do entities need to know about comments?

I personally would aim for comments decoupled from the entities. Your comment class could depend on a ParentId value object:

final class ParentId
{
    private string $entityName;
    private string $entityId;

    public function __construct(string $entityName, string $entityId)
    {
        $this->entityName = $entityName;
        $this->entityId = $entityId;
    }
}

This value object would act as a link to your entities, but it's not related to entities directly. It could be saved in the db as embeddable.

Your entities would implement an interface e.g. ProvideCommentParentId:

interface ProvideCommentParentId
{
    public function commentParentId(): ParentId;
}

This would make it straighfroward to fetch entity related comments for display, e.g. in the controller action:

$comments = $commentsRepository->findLatestCommentsByParentId($entity->commentParentId());

Hope this was helpful!

Kind regards,
Marek

@parijke
Copy link
Author

parijke commented Jul 2, 2020

Wow what a fantastic answer. I don't know yet if it will work (or if I understand it fully) but from a little distance it makes sense. I am going to investigate on your answer to get some PoC done with it. I'll let you know

@parijke
Copy link
Author

parijke commented Jul 8, 2020 via email

@mareg
Copy link
Owner

mareg commented Jul 8, 2020

Hi Marek, I read it several times, and I think I'll get it. I am going to do a PoC repo to test/ try /develop it. If I understand correctly, the relationship will then be managed manually, not by doctrine, am I correct (because of the absense of a valid FK)? Anyway I will let you know how the PoC goes, maybe asking for a peek :-)

That's correct - no need for FOREIGN KEY in the scenario I've described above. Yes, you'll have to manage relation by yourself, but that gives you extra flexibility and simplicity in return. Happy to have a look at your PoC 👍

@parijke
Copy link
Author

parijke commented Jul 16, 2020

Hi Marek,

I overlooked one of your questions: My question would be - do entities need to know about comments? Yes, they do.

I tried to do a oversimplified version of this in https://github.com/parijke/commentable-test/

I created a Comment entity who will receive the parent object and set the realtion in it's constructor. Now the challenge is to get the relevant collection in the parent entity. Something like getComments() should retrieve a collection of the related comments.

@mareg
Copy link
Owner

mareg commented Jul 24, 2020

Hey @parijke 👋

I overlooked one of your questions: My question would be - do entities need to know about comments? Yes, they do.

My counter question would be - why do commentable entities need to know about comments?

I tried to do a oversimplified version of this in https://github.com/parijke/commentable-test/

At first I've tried to modify your code to show better what I meant, but then I decided to create a slightly cleaner solution, so you pick bits you want: https://github.com/mareg/commentable

In my proof of concept example both Post and Video are not aware of comments, but they're Commentable. I've created it as a simple API, but if you wanted html responses, then it's just a matter of changing responses from the controllers. You'll notice that my view controller actions query database separate for entity (done by doctrine param converter) and comments.

I created a Comment entity who will receive the parent object and set the realtion in it's constructor. Now the challenge is to get the relevant collection in the parent entity. Something like getComments() should retrieve a collection of the related comments.

Why do you need all comments in the parent entity? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants