diff --git a/Intro_to_Solid.md b/Intro_to_Solid.md index 39d8381..49a0a03 100644 --- a/Intro_to_Solid.md +++ b/Intro_to_Solid.md @@ -6,7 +6,7 @@ SOLID coding is a principle created by Robert C.Martin, he is a famous computer SOLID is an acronym for his five conventions of coding. With their conventions, you can improve the structure of your code, reduce time to implement changes and technical debts, etc. It is a collection of best practices. -And it was developed through this decades. +And it was developed through this decade. Principles of SOLID acronym are: * The Single-Responsibility Principle (**SRP**) @@ -15,15 +15,120 @@ Principles of SOLID acronym are: * The Interface Segregation Principle (**ISP**) * The Dependency inversion Principle (**DIP**) -The first conventions is **SRP**, that means that all classes of your code must do one thing. +The first convention is **SRP**, that means that all classes of your code must do one thing. That is an important principle. That is the best way to work with others people in the same project. Version control is easier, -You will never have _Merge conflicts_, because other people works in an another operations. +You will never have _Merge conflicts_, because other people work in other operations. So, he will never have two same things in the code. +### Single-Responsibility +Let's start something ! +We will make common mistake that violate **SRP** and correct them. +Let's code a bookstore invoice. + +```python +class Book(object): + def __init__(self, name, authorName, year, price, isbn): + self.name = name + self.authorName = authorName + self.year = year + self.price = price + self.isbn = isbn +``` + +As you can see, there is a class named Book with some fields. +This fields are public and characterize a book. + +OK ! Now we can start the invoice class. +This class will calculate the final price for a customer. + +```python +class Invoice: + def __init__(self, book, quantity, discountRate, taxRate, total): + self.book = book + self.quantity = quantity + self.discountRate = discountRate + self.taxRate = taxRate + self.total = total + def calculateTotal(self): + self.price = ((self.book.price - self.book.price * self.discountRate)*self.quantity) + + self.priceWithTaxes = self.price * (1 + self.taxRate) + + return self.priceWithTaxes + + def printInvoice(self): + print(self.quantity, "x", self.book.name,"", self.book.price, "$"); + print("Discount Rate: ", self.discountRate) + print("Tax Rate: ", self.taxRate) + print("Total: ", self.total) + def saveToFile(self, fileName): + pass +``` + +Alright, now we have the _Invoice_ class, he had 3 methods (calculateTotal, printInvoice, saveToFile) and some fields too. +Why this code violate the first convention of **SOLID** ? + + +The _printInvoice_ method violate this one because the **SRP** told us to make just one thing per classes. +Here, our printing logic is in the same class than _calculateTotal_ method. +So, the printing logic is mixed with business logic in the same class. +As you think, the _saveToFile_ method violate this convention too. + +Let's correct this example. +```python +class InvoicePrinter(object): + def __init__(self, invoice): + self.invoice = invoice + def printInvoice(self): + print(self.invoice.quantity, "x", self.invoice.book.name,"", self.invoice.book.price, "$"); + print("Discount Rate: ", self.invoice.discountRate) + print("Tax Rate: ", self.invoice.taxRate) + print("Total: ", self.invoice.total) +``` + +```python +class InvoicePersistence(object): + def __init__(self, invoice): + self.invoice = invoice + + def saveToFile(self): + pass +``` + +We have now two others classes, _InvoicePrinter_ class and _InvoicePersistence_ class. +The _InvoicePrinter_ is used to print information. +And the _InvoicePersistence_ is used to save information. + +With these three classes, we respect the first principle of **SOLID**. + +### Open-Closed Principle + +This principle says that classes are open for extension and closed to modification. +Extension mean news functionality and modification mean modifying your code. +If you want to add new functionalities, you are able to add it without manipulating the existing program. +If you touch the existing code, you have a risk to have news bugs. +So, if you want to add something else, you can use abstract classes and help of interface. + +Ok so, let's add new functionality in the _InvoicePersistence_ class. + +```python +class InvoicePersistence(object): + def __init__(self, invoice): + self.invoice = invoice + + def saveToFile(self): + pass + + def saveToDataBase(self): + pass +``` +The _saveToDataBase_ method is used to save information in a Data Base. +We have modified the _InvoicePersistence_ class. +This class will be more difficult to make easily extendable. \ No newline at end of file