master #12
			
				
			
		
		
		
	| 
						 | 
					@ -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.
 | 
					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.
 | 
					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.
 | 
					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:
 | 
					Principles of SOLID acronym are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* The Single-Responsibility Principle (**SRP**)
 | 
					* The Single-Responsibility Principle (**SRP**)
 | 
				
			||||||
| 
						 | 
					@ -15,15 +15,120 @@ Principles of SOLID acronym are:
 | 
				
			||||||
* The Interface Segregation Principle (**ISP**)
 | 
					* The Interface Segregation Principle (**ISP**)
 | 
				
			||||||
* The Dependency inversion Principle (**DIP**)
 | 
					* 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 an important principle.
 | 
				
			||||||
That is the best way to work with others people in the same project.
 | 
					That is the best way to work with others people in the same project.
 | 
				
			||||||
Version control is easier, 
 | 
					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.
 | 
					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.
 | 
				
			||||||
		Loading…
	
		Reference in New Issue