Now let's discover one of my favorite principles, which is the open closed principle.
That's the O in solid.
So here we got an application.
We have an invoice class with a property called amount.
We have a billing service.
That one has a method called Calculate total.
It's just returning the total price basically.
Then we simply create an invoice.
We create an instance of that billing service.
And we call that method.
When we start the application we will get a console entry total 100.
Great.
The open close principle now gives us a way, or grants us access to a way on how we can or should extend
the functionality of our software.
Our application here works and is well designed as of right now.
But what would you do if I tell you now that you should create another type of invoice, for example,
a discounted invoice and the open closed principle here says that we do not modify the existing logic
that is working right.
Our application here works fine, absolutely well designed, working perfectly fine and we will not
modify the logic here.
Public class invoice and billing service instead of modifying our existing algorithms and well, stuff
that we have in our application, we want to create new classes and extend the functionality and rely
on what's working already.
That basically means that if we would create or we need to create a discounted invoice, for example,
we would simply create a public class discounted invoice.
And again, we do not want to duplicate ourselves.
So we do not want to copy over public double amount or whatever.
Instead, we want to build upon what's already existing right open closed patterns.
So we are open for extension, but we are closed for modification.
Then we are allowed to add extension.
That's what we're doing by using inheritance.
But we are not allowed to modify for only for the purpose of an update.
Right?
Just for adding new stuff.
We're not allowed to modify the existing logic because we could cause bugs that are for sure unwanted.
So public class discounted invoice is inherited from our invoice for sure.
Since this one is public here, we will now have the amount property inside of our discounted invoice
two and we can add an extension here.
Another property which is a double and the name is for sure discount.
That's the first part.
So we have extended our application by discounted invoice by using what's already working the invoice,
and then add the changes that we need to make.
So a discount here for example, we will do exactly the same with a new class billing service.
We will call it discounted billing service.
And this one.
Is inherited from our billing service.
Now we have to make some additional modifications here because for our discounted billing service here,
we have to override the logic of our calculate total method.
Therefore we will make this public and then virtual so that our new discounted billing service can override
it.
Public override double right.
So here we got it virtual.
And then we override it calculate total.
Again we take in invoice and we will keep our base calculate total here.
But for the case that the invoice that we have here if invoice from the parameter then we use the Is
keyword to check if it's of a specific type is discounted invoice case.
Let's provide a name here.
Discounted invoice.
Right.
So now we know okay we have a discounted invoice.
So again this invoice here is of type discounted invoice.
Then we want to return discounted invoice amount.
Right.
That's coming from this one here it's inherited.
So we can call amount and then we subtract the discount invoice discount okay.
So as you can see we have not modified any of our existing logic related to the billing service.
And um, our invoice class here.
Instead of that we have made use of the open closed principle.
So we have not modified but we have extended our functionality.
We created a new billing service right.
And created a new type of invoice.
So let's go ahead to our um program here so that.
We can just test it.
Let's create a discounted invoice.
Discounted invoice equals to new discounted invoice.
Let's just add an amount here.
Let's say it's equals to 100 and the discount is set to 25.
Then we create a new instance of our discounted billing service right.
Discounted billing service new discounted billing service.
And then we simply log the value to the console.
So Console.WriteLine.
Then take the discounted billing service dot calculate total.
And then we want to put in our discounted invoice.
Just like this works fine.
Now I only want to log it to the console, so it's okay to put that into the parentheses.
If you would like to use that value later on.
You want to do it just like here.
Put it into a variable that you can use later on.
Great.
So save.
Then we should see that the first invoice will be 100 and the second one our extension will be 75.
There we go.
Alrighty, so that works totally fine.
We have now made use of the open closed principle.
Open for extension but closed for modification.
So do not modify what's already working.
Simply extend the functionality that you need.
In that way, making updates or adding new features to your software is less buggy, right?
Or massively reduces the chance of adding bugs to your software.