12 toward solid code
TRANSCRIPT
![Page 1: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/1.jpg)
Moving toward SOLID code
![Page 2: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/2.jpg)
Refactoring is changing the internal implementation to make it more maintainable
� If the user sees a change, it isn't refactoring
![Page 3: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/3.jpg)
Agile projects advocate refactoring mercilessly
![Page 4: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/4.jpg)
YAGNI You Aren't Going to Need It
![Page 5: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/5.jpg)
SOLID Principles
Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
![Page 6: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/6.jpg)
� asdf
![Page 7: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/7.jpg)
Single Responsibility Principle “If a class has more then one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class’ ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.”
- Robert C. Martin
![Page 8: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/8.jpg)
Single Responsibility Principle � A class should have one and only one
reason to change � Maybe we should call it the Single
Change Reason Principle
![Page 9: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/9.jpg)
Problem: We have a user interface that reads from/writes to the database. This is not cohesive
UI
![Page 10: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/10.jpg)
Goal: To get the business logic out of the UI. Let the UI do what it does exclusively
Business Logic
UI
![Page 11: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/11.jpg)
Problem: DB logic In the UI code public void Click(object o, EventArgs e) { var name = txtName.Text; var phone = txtPhone.Text; var db = new SqlConnection(); db.Open(); var sql ="insert into ... name ..."; var cmd = new SqlCommand(sql, db); cmd.ExecuteNonQuery(); }
![Page 12: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/12.jpg)
Solution: Create a Person class public class Person { public string Name { get; set; } public string Phone { get; set; } public void Save() { //Write to database here //Connection, Command, ExecuteNonQuery } public Person Read(int Id) { //Read from database here //Connection, Command, ExecuteNonQuery } }
![Page 13: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/13.jpg)
Problem: We still have db logic in the business logic
Business Logic
UI
![Page 14: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/14.jpg)
Business Logic
Infrastructure
UI
Solution: Create a DB layer
![Page 15: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/15.jpg)
Create a repository class Public class PersonRepository { public void Save(Person) { //Write to database here } public Person Read(int Id){ //Read from database here return thePerson; } }
![Page 16: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/16.jpg)
New class w/o DB logic public class Person { public string Name { get; set; } public string Phone { get; set; } public void Save() { var r = new PersonRepository(); r.Save(this); } public Person Read(int Id) { var r = new PersonRepository(); return r.Read(Id); } }
![Page 17: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/17.jpg)
� asdf
![Page 18: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/18.jpg)
Open-Closed Principle Modules that conform to the open-closed principle have two primary attributes. 1. They are “Open For Extension”.
This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications.
2. They are “Closed for Modification”. The source code of such a module is inviolate. No one is allowed to make source code changes to it.
- Robert C. Martin
![Page 19: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/19.jpg)
Open-Closed Principle � Classes should be open for extension but
closed for modification � To properly change behavior, you should
inherit from it and add or override functionality in the child class
![Page 20: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/20.jpg)
Examples � Physical world
� Ryobi lawn tool
� In the Matrix � Visual inheritance in WinForms or WebForms � Custom exceptions
![Page 21: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/21.jpg)
� sdfsd
![Page 22: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/22.jpg)
Liskov Substitution Principle “If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.”
- Barbara Liskov “Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.”
-Robert Martin
![Page 23: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/23.jpg)
Liskov Substitution Principle in real-people words. � Any object must be semantically similar to
everything above it in the inheritance tree � No matter how poorly named they are � Semantically substituted, not syntactically
substituted
![Page 24: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/24.jpg)
Example: Bike & Motorcycle public interface IBicycle !{! int speed;! void Brake();! void Accelerate();!}!public class Motorcycle : IBicycle!{! public Motor Engine { get; set; }!}!
![Page 25: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/25.jpg)
� sadf
![Page 26: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/26.jpg)
Interface Segregation Principle “This principle deals with the disadvantages of ‘fat’ interfaces. Classes that have ‘fat’ interfaces are classes whose interfaces are not cohesive. In other words, the interfaces of the class can be broken up into groups of member functions. Each group serves a different set of clients. Thus some clients use one group of member functions, and other clients use the other groups.”
- Robert Martin
![Page 27: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/27.jpg)
Interface Segregation Principle � An implementing class should not be
forced to depend on an interface that it doesn’t need
� Split fat interfaces up � Very much like SRP
![Page 28: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/28.jpg)
Example: All-in-one printer
28
![Page 29: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/29.jpg)
� sadf
![Page 30: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/30.jpg)
Dependency Inversion Principle “What is it that makes a design rigid, fragile and immobile? It is the interdependence of the modules within that design. A design is rigid if it cannot be easily changed. Such rigidity is due to the fact that a single change to heavily interdependent software begins a cascade of changes in dependent modules.”
- Robert Martin
![Page 31: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/31.jpg)
Dependency Inversion Principle � Depend on interfaces, not concrete
implementations
![Page 32: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/32.jpg)
Example Problem: The business classes are worthless without the DB logic. They're too tightly coupled.
Business Logic
Infrastructure
UI
Person Repository
Person
![Page 33: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/33.jpg)
� Goal: Have a business object that maintains its state in the database
Business Logic
Infrastructure
UI
IPerson Repository
Person Repository
Person
![Page 34: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/34.jpg)
Step 1: Create an interface public interface IPersonRepository { public void Save(); public Person Read(int Id); } public class PersonRepository : IPersonRepository { //Same concrete implementations }
![Page 35: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/35.jpg)
Step 2: Using the interface public class Person { public string Name { get; set; } public string Phone { get; set; } public void Save() { IPersonRepository r = new PersonRepository(); r.Save(this); } public Person Read(int Id) { IPersonRepository r = new PersonRepository(); return r.Read(Id); } }
![Page 36: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/36.jpg)
Step 3: Pass an IPersonRepository into the constructor public class Person { private IPersonRepository ipr; public string Name { get; set; } public string Phone { get; set; } public Person(IPersonRepository PersonRepo) { ipr = PersonRepo; } public void Save() { ipr.Save(this); } public Person Read(int Id) { return ipr.Read(Id); } }
![Page 37: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/37.jpg)
Business Logic
Infrastructure
UI
Person Repository
Person
Step 4: Move the IPersonRepository to the Person Business Logic project
IPerson Repository
![Page 38: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/38.jpg)
� sdfgd
![Page 39: 12 toward solid code](https://reader033.vdocuments.mx/reader033/viewer/2022060108/554f66dcb4c9058a148b4bb0/html5/thumbnails/39.jpg)
Summary � We can't write perfect code and we shouldn't try � It helps us to write faster if we use good design
patterns and know we'll be back later to refactor the code
� We should use the SOLID design patterns to make more maintainable code � S - Each class should do one only one thing � O - Classes can be inherited, but not changed � L - Design to Interfaces, not classes � I - Classes shouldn't rely on things they don't use � D - Code should depend on interfaces, not classes