Another very important principle of clean code is the SRP principle.
Single responsibility principle.
So the single responsibility principle is focused on creating classes or what classes should do.
Let's take a look at the project that I have prepared here.
Again I think that this is best explained by example.
We have a class program here.
We have our void main.
We have an order again and an order service.
And we can simply add an order by calling the order service.
This is how an order looks like ID product name, quantity, price, nothing special.
And here we got our order service.
This is the main part.
We have one class called Order service.
Inside here we have a field orders.
Then we have a method add order.
We have a method log order and we have a method notify customer.
So the good thing about this code already is that the logic.
So for example logging notifying and adding already is separated.
So we are not putting everything like the entire logic into one single method.
We have splitted it up into multiple methods.
So that's the good part already.
As you have learned throughout this section, however, the single responsibility pattern says that
one class should only have one responsibility.
So here in our order service, we have multiple responsibilities adding orders, logging orders, and
notifying customers.
Those three are entirely different from the responsibility.
You know you could group them adding order, deleting order, getting an order and all of that.
That would be one responsibility, right?
But logging has nothing to do with managing, so adding or removing them.
Nor does notifying has any responsibility or is related to the order.
Right?
So in that case, we would have to split up the order service into multiple subclasses so that each
class only has one responsibility, one class to actually handle the orders, adding, removing, and
so on.
One class that is only here for notification, and one also order notification, and one class that
is here for logging the order.
In that way we will have followed the SRP principle single responsibility.
So remember it's about building classes that have a single responsibility.
Alrighty.
So let's do this here.
Let's take that code and let's refactor it.
We keep our order service because that one is perfect for adding, removing, updating and getting orders.
But we will create separate classes for the logger and for the notify customer.
So for the sake of this video, I will create those classes in the same file here.
For sure in real world you would create new files right?
So new files for those classes.
Great.
Let's start with the logger here at the bottom.
Let's create a new class public class order logger.
This one is for logging orders.
The second class public class order notifier.
This one is for sending notifications related to orders.
Let's simply copy those methods that we have right here.
Notify customer.
Let's just cut it out and paste it back in here into the class.
Same for this one log order.
Let's cut it out and put it into our order logger.
Great.
So now our classes look like this.
I will just zoom out for a second.
We got the public class or the service, or the logger and order notifier.
So each of them is built for a single responsibility.
Right.
Or the service handles the access adding, getting, removing of orders or the logger logs orders order
notifier notifies.
So the key question now is how can we make this work again.
Because when we add an order, you can see that we want to log and notify the customer.
Right.
So therefore we have to go to our methods here that we have and they are set to private.
And we have to make them public for sure.
So simply set the access modifier.
Just zoom in again from private to public.
Same for this one here.
This will allow us to call those methods from an order logger instance.
And now another key part takes place inside of our order service where we handle our orders.
Right.
That would be like the main part of our use case.
We handle orders.
So we need that order service to get access to the orders, save them, etc. and then we want specific
additional functionality to take place, like logging and notifying inside of the order service.
Let's go ahead and create a private.
Then we want to use the order logger.
First order logger, let's call it order logger equals to a new instance of an order logger.
Same for the private order notifier.
Order notifier equals to a new instance of the order notifier.
Just like this, we can just group them together.
Now we have a list of orders.
We have an instance of the order logger and the order notifier.
And now we can for sure use them.
So order Logger.log order order notifier dot notify customer.
There we go.
Now please notice that our order service here acts like the orchestrator.
So this is the main part for handling our orders right.
So here it's okay to create instances of other classes which kind of like add side effects like logging
and notifying.
When we access add, remove update our orders.
Right.
You know there are many other design patterns that you could use.
We could for example, create events and delegates and all of this.
But our order service can be seen as the orchestrator.
So it's okay to add other classes here like our order logger and order notifier, and then finally add
them.
It would not be such a good practice to go to the order logger and then create a field here that relates
to the order notifier.
And then we have to call the order logger, just to call the method to notify the customer.
That will be a bad practice right.
So we have the order service the orchestrator.
And then we have smaller subclasses which add additional functionality related to orders like logging
and notification.
Then we take our order service.
Most of the time you will see this as a manager or as a service, and inside this orchestrator you can
then use your classes that you have created to call additional functionality.
Alrighty, and this is an example of how you can make use of the single Responsibility principle.