How to implement the single-responsibility principle?

Good day!
There is a class named ProductController and it's add method the add a product. I understand that this method should only be adding items to the database, according to one of the SOLID principles.
But I turns out that after you add a product and its characteristics in the database using the id of the added items, have implemented a number of additional methods and queries, necessary for the formation of filters in the store.
Tell me, please, how am I supposed to post in different methods or classes, how to form an abstraction, and that is all in the forehead goes.
March 19th 20 at 09:09
5 answers
March 19th 20 at 09:11
That's a good question.

Let's start with the fact that according to the single-responsibility principle in the controller no add to database should not be.
The controller, in General, is the most miserable part of the web application. His task is to retrieve data from http request and pass them to the model and then pass the response back to the browser. Stupid "bring-bring".
But the model already needs to be written to the database, to verify the validity of the data, and do all other gestures.

to form an abstraction, we must know the problem is not at the level of the stub vague phrase "a number of additional methods and queries, necessary for the formation of filters in the store." What kind of queries? What does the filters do? As the implemented interface to the database is the ORM, the direct work with the database, something else?

Based on the information from the comments here useful helper service. A separate class that implements the addition of the product.

That is, the controller pulls the validator and looks the answer.
If there is a validation error, it shows the form back
If there are no errors - pulls the service to add a product and then redirects somewhere

And the service already performs all the actions that are required when adding a product.

In principle, validation is also possible in the service, but then you have to consider the reverse communication with the controller.

The most important thing that you've got to understand that the Model is not an interface for interaction with one class to one table in the database (as it is still considered by most), and the totality of the logic of classes and modules implementing the business logic of the application. That is, the model includes the mappers, and services, and repositories, and anything - except for the interfaces with the outside world, such as controllers.
I don't agree with you about helper. In my opinion this is a bad decision that litter the code and introduces a lot of ambiguity. Tomorrow another developer can create another controller which will also be added to the product. Uses a method from the model and no additional deysvtiya will fail.
In my opinion the best after the product is created to generate an event, which will react members and will produce additional steps are required.

In principle, validation can also be a helper, but then you have to consider the reverse communication with the controller.

And this is all you can bring to the system level before resorting to the controller. - theodora commented on March 19th 20 at 09:14
Tomorrow another developer to create another controller which Nuno will be the item.

excuse me? - Jerel commented on March 19th 20 at 09:17
Based on the information from the comments here useful helper. A separate class that implements the addition of the product.


it is the task of the service - breanna.Kub commented on March 19th 20 at 09:20
@breanna.Kub, I'm easy to rename - Jerel commented on March 19th 20 at 09:23
@theodora, I think the author of the question it would be something transcendent. Better something simple. The project is likely, it is also quite simple - rahsaan.Reichel commented on March 19th 20 at 09:26
@Jerel , fingers ripe for the idea, I procene. Corrected to:
Tomorrow another developer can create another controller which will also be added to the product.


@rahsaan.Reichel, there is nothing extraordinary. The author is still a student and it's time to show him the correct approach, and do "faster now" (which promises only a technical long and broadc in the code). - theodora commented on March 19th 20 at 09:29
@theodora,
Tomorrow another developer can create another controller which will also be added to the product.

well, this controller (or a controller, and a command-line utility to import products from a file) will pull the same service. - Jerel commented on March 19th 20 at 09:32
March 19th 20 at 09:13
The principle of a single responsibility does not mean the implementation in the form of a single action or a single line of code.
the add method adds that he is still there is does not matter. most importantly the ultimate goal. the rest is just auxiliary mechanisms that if you need to add - that nobody forbids to use them.
No, I'm after adding an item to the database method is called addInfoToFilter that the product has a very indirect relationship using only the id assigned to the record. - casper_Kohler59 commented on March 19th 20 at 09:16
@casper_Kohler59, and what this filter does? - Brook54 commented on March 19th 20 at 09:19
March 19th 20 at 09:15
The controller pulls the service which has methods for working with the product.
ProductService->addProduct(...)

if this ProductService will make adding/removing comments to the product then this is a violation of the principle of single responsibility
probably he needs the service class at the application level and not the domain
something like app/Services/Catalog
that works with goods, filters and so on - breanna.Kub commented on March 19th 20 at 09:18
March 19th 20 at 09:17
Advice is to read Robert Martin's clean architecture
At least the Chapter about SRP
To pay attention, "Martin defines a responsibility as the reason for the change and concludes that classes must have one and only one reason to change." Pay attention when permitted to leave everything in the same class and when it is desirable to separate class.

There is little experience to break into layers as in the examples of pure architecture (online enough)
Or fill the cones and think why didn't I do as it was in examples)
Remember the goal of solid is very pragmatic - to make code that is easily maintained. Always remember that.
March 19th 20 at 09:19
As already wrote above, the entire business logic is better placed at the level of the model and the controller to write "thin".

In order not to violate the principle of single responsibility, you can use the Observer pattern. Model after adding an item to create an event that will be able to subscribe to other components of the application. The code responsible for different actions, will be located in different services of the system, and thus is poorly connected among themselves
https://refactoring.guru/ru/design-patterns/observer
As already wrote above, the entire business logic is better placed at the level of the model and the controller to write "thin".


Ie I understand correctly, under the principle of single liability you propose in the model have the ability to:
- contain business logic
- use work with the data source (DBMS)
- use the validation of the model
to use an implementation of the model (entity)

? - breanna.Kub commented on March 19th 20 at 09:22
@breanna.Kub, the layer model can contain all of the above. With regard to the principle of single liability, it is possible to implement within the model, making the validation work with the database and other actions in various system components - elijah_Mayert commented on March 19th 20 at 09:25
@elijah_Mayert, I thought that the model, which belongs to the Product class should only contain logic related to database and directly product. And the data validation, filters, exceptions, etc. are the other components. - casper_Kohler59 commented on March 19th 20 at 09:28
I agree, PS anemic domain model - breanna.Kub commented on March 19th 20 at 09:31

Find more questions by tags PHP