Support the ongoing development of Laravel.io →
posted 10 years ago
Architecture
Last updated 2 years ago.
0

Good question.

The immediate thought process I would think of when going through this question is - is there a class I am already using that can handle the functionality without breaking the Single Responsibility Principle? If there is, then yes - you've over-complicated/over-engineered it. If you haven't, then you're on the right track.

In respect to your form objects - I actually have setup a more generalised solution - services. Services handle particular use-cases, and will talk to validation and persist data to storage via the repositories. The only issue I take with the term "Form", is that it stipulates that that data will only ever come from a form. And this is probably true for 90% of cases - but what about the times when you have to run a cron-job, or you're seeding data.etc?

I think you're on the right track, but there appears to be a lot of redundant code in your example, in that - it looks like code that would show up in many different controller actions. My thought there is what can you do to simplify it? Exceptions are a good way to do this, which I talk about in my Validations presentation at Laracon. That way you can write your code with the assumption that everything has worked fine - and have response handlers deal with those exceptions when they arise, thereby cutting down your controller code substantially.

Hope that helps :)

Last updated 2 years ago.
0

Thanks Kirk,

That is definitely food for thought.

I'm scratch my head with regards to your idea of using Custom Exceptions and I can see how this would cut a load boiler plate out.

You also mention "services". I am using Services in my app. Admittedly as a self taught OOP dev - its my notion/heavily influenced by the internet of what that entails.

This is my project structure.

Project Structure

In regards to Single responsibility - I am not certain how to achieve this.

My test project is basically creating a Contact book.

Party = Person or Org with relations X number of telephone X number of Emails X number of Addresses

To Save a New contact, I am using a Repository. Injecting via Service Providers the relevant models and doing the logic in the STORE method.

If I lose my Form Object that is currently handling Validation - Do I put it in the Repo?

The light bulb has gone on in respect of handling failed validation - Custom Exception and event Listener.

But the actual code that exists to loop my JSON payload, then test against the relevant models Repo Injected Validator has to sit some where. If I put this in the REPO does this break single responsibility.

I feel this simple scenario is holding me back from being able to fly the project.

I feel I need someone qualified (more qualified than me) to say - YUP thats the way you do it. ! OR No this is a better way.!

Based on what you write above and taking what experience I have from learning Solo - my best guess on moving forward would be:

  1. Custom Exception with Event Listener.
  2. Create some sort of secondary Service - that handles the code that interacts with the payload and the repo.

Im still not sure.

You write:

In respect to your form objects - I actually have setup a more generalized solution - services. Services handle particular use-cases, and will talk to validation and persist data to storage via the repositories.

I would love to hear more on this. Anything specific or maybe an example.

Once again - THANK YOU - for taking the time to help.

Last updated 2 years ago.
0

Okay - so firstly, I will admit that your follow up questions I'm finding a little hard to read, so I apologise if the below answer does not address your needs.

Secondly, repositories should ONLY be for creating and managing database objects. What do I mean by this? I mean that any call you make to a repository, should only ever be persisting data, deleting data, or retrieving data. If it's doing anything else for a particular model, then it's doing too much and breaking single responsibility principle.

For validation - put the validation call in the service, but have a separate validation class PER USE CASE. This will allow validation to do only that. I'm working on an article that will highlight this a little more clearly, as well as an article of how to use repositories reponsibly. Let's say for example, you have a user registration use case, the code path should look like this:

  1. POST to /users/register/ (or something)

  2. User controller that handles registration should have a dependency on the UserRegistration service.

  3. UserRegistration service class calls validation, something like:

    (new UserRegistrationValidation($input)->validate());

  4. If validation fails, it'll throw an exception which you can handle

  5. Next line should be dealing with the users repository:

    $user = $this->usersRepository->registerWith($input);

Make a call to the repository, create the user. You then have a user object you can do whatever you want with.

return $user;

This should be your last line in your service's register method.

Now, back in your controller, you simply handle the $user however you want:

$this->session->logIn($user); // or something of that nature

return Redirect::to('some action');

This obviously isn't the only way to deal with it, there are many different approaches. The problem with using lots of services, or commands if you'er going the DDD route, is how to handle all those layers. What used to be a 3-layer approach (MVC), is now fast becoming 5 or 6 layers. You don't want to be passing back information all the time, because an error that occurs 6 layers down will be very hard to manage (which is why you want to start using exceptions more).

In regards to your structure - I'd break it down by domain/module. For example, have a Users folder that has all the validation, services, models and repositories specific to users.

Whenever you create or delete or save a user - fire an event, then let other modules deal with related data/content.

Hope that helps!

Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

qazjayp99 qazjayp99 Joined 27 Jun 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.