SOLID Principles
Every developer
should know
TOAN NGUYEN
TO A N - H U U . N G U Y E N @ KO L E K TO . N L
NGUYENTOANUIT
Agenda
What are SOLID?
Why should we care?
How can we apply SOLID principles?
◦ S – Single responsibility principle
◦ O – Open–closed principle
◦ L – Liskov substitution principle
◦ I – Interface segregation principle
◦ D – Dependency inversion principle
SOLID - TOAN NGUYEN
About me
Nguyen Huu Toan
Senior Dev – skype nguyentoanuit@gmail.com
SWGLayer team
https://app.kolekto.nl
SOLID - TOAN NGUYEN
What is SOLID?
“It is not enough for code to work.”
- Robert C. Martin
SOLID is five basic principles which help us write clean code
◦ Understandable
◦ Easier to maintain
◦ Easier to extend
The abbreviation SOLID was introduced by Michael Feathers
But the concept of SOLID principles were first introduced by Robert C. Martin
in his book, Design Principles and Design Patterns.
So let see how SOLID can help us be stronger
SOLID - TOAN NGUYEN
Why should
we care?
BUT WAIT A MINUTE!!!
WHY SHOULD WE NEED
TO APPLY IT?
SOLID - TOAN NGUYEN
Why should we care?
Can we just make it work without following these principles?
Finish the business rules/PBI and delivery functionality to
client are our main task, why do we need to care about these
annoying rules/principles?
SOLID - TOAN NGUYEN
Why should we care?
Yes, of-course.
BUT..... the functionality that you create today has a good
chance of changing in the next release.
The more you care about good code today, the more you are
loved by your teammate later
SOLID - TOAN NGUYEN
Why should we care?
So I will make it work first and refactor later on?
SOLID - TOAN NGUYEN
Why should we care?
Yes, sure! But it will be very expensive.
SOLID - TOAN NGUYEN
Why should we care?
“People will forget how fast you did a job, but they remember
how well you did it!”
- iDev
SOLID - TOAN NGUYEN
How can we
apply SOLID
principles?
S – Single responsibility principle (SRP)
O – Open–closed principle (OCP)
L – Liskov substitution principle (LSP)
I – Interface segregation principle (ISP)
D – Dependency inversion principle (DIP)
SOLID - TOAN NGUYEN
S – Single responsibility principle
“A class should only have a single responsibility”
So that, a class should have one and only one reason to change.
SOLID - TOAN NGUYEN
S – Single responsibility principle
public class Production
{
public Guid Id { get; set; }
public string Title { get; set; }
public string ShortDescription { get; set; }
public string ImageUrl { get; set; }
public int RemainItems { get; set; }
public string CheckStatus()
{
if (RemainItems > 500)
{
return "There are a lot of remaining items";
}
else if (RemainItems <= 500 && RemainItems > 200)
{
return "Warning: We should buy more";
}
else
{
return "Red warning: We need by more";
}
}
}
SOLID - TOAN NGUYEN
Inventory
business
S – Single responsibility principle
public void SendEmail(EmailData emailData)
{
var email = new
{
from = emailData.From,
to = emailData.To,
message = emailData.Message
};
graph.sendEmail(email);
}
SOLID - TOAN NGUYEN
S – Single responsibility principle
SOLID - TOAN NGUYEN
public void SendEmail(EmailData emailData, bool generateAttachment)
{
var email = new GraphEmail
{
from = emailData.From,
to = emailData.To,
message = emailData.Message
};
if (generateAttachment)
{
var document = new
{
title = emailData.AttachmentName,
content = pdfGenerator.GeneratePDF(emailData.Message)
};
email.attachment = document;
}
graph.sendEmail(email);
}
Generate attachment is not
a job of send email function
Avoid violate SRP
1. Long method
2. Boolean flag
3. Class (service) serve many operations
4. Always ask why is the responsibility of class/service/module when extending
SOLID - TOAN NGUYEN
Benefits of SRP
1. Easy to follow/understand
2. Maintainable
3. Test easily
4. Easy to extend
SOLID - TOAN NGUYEN
Open–closed principle
Entities should be open for extension, but closed for modification.
SOLID - TOAN NGUYEN
Open–closed principle
SOLID - TOAN NGUYEN
Open–closed principle
SOLID - TOAN NGUYEN
Open–closed principle
SOLID - TOAN NGUYEN
User form
Open–closed principle
SOLID - TOAN NGUYEN
Is it fully follow OCP?
Open–closed principle
As application grow up, a lot of new behaviors of the form will be added such as
◦ Handle dirty form
◦ Confirmed/warning message
◦ User only can view data, can’t make a change in the form
◦ Show overlay when data is loading
◦ more and more …..
SOLID - TOAN NGUYEN
Open–closed principle
SOLID - TOAN NGUYEN
Open–closed principle
Composition instead of inheritance
SOLID - TOAN NGUYEN
<form>
<FormContext.Provider value={setupContextForm()}>
<Header />
<DirtyCheck />
<BaseWarningMessage />
<ConfirmMessage />
<Messages />
<BaseValidation />
<UserFormFields />
<FormButtons />
....
</FormContext.Provider>
</form>
Benefits of OCP
1. Reusable and maintainable
2. Avoid regression bugs
3. Extend easily and quickly
SOLID - TOAN NGUYEN
Avoid violate OCP
1. Using inheritance
2. Using Composition
3. Using interface
SOLID - TOAN NGUYEN
Liskov substitution principle
Let Φ(x) be a property provable about objects x of type T. Then Φ(y)should be true for
objects y of type S where S is a subtype of T.
Developer language
"Objects in a program should be replaceable with instances of their subtypes without
altering the correctness of that program.“
Related to???
Open – close principle
SOLID - TOAN NGUYEN
Liskov substitution principle
SOLID - TOAN NGUYEN
public class Airplane
{
public string Name { get; set; }
public virtual void TakeOff()
{
Console.WriteLine("Hello madam and gentleman, we are taking off");
}
public virtual void Landdown()
{
Console.WriteLine("Hello madam and gentleman, we are landing");
}
public virtual void Up()
{
Console.WriteLine("Air plane go up");
}
public virtual void Down()
{
Console.WriteLine("Air plane go down");
}
}
public class TraditionalAirPlane : Airplane
{ public TraditionalAirPlane()
{
Name = “Traditional one";
}
}
Liskov substitution principle
SOLID - TOAN NGUYEN
static void Main(string[] args)
{
var airPlane = new BoeingB52();
var pilot = new Pilot(airPlane);
pilot.HandleAirePlane();
}
Liskov substitution principle
SOLID - TOAN NGUYEN
public class SmartAirplane : Airplane
{
public bool AirPlaneUp { get; set; }
public bool OffAutoDetection { get; set; }
public SmartAirplane()
{
Name = "I am smart air plane" ;
}
public override void Up()
{
if (AirPlaneUp && !OffAutoDetection)
{
throw new System. Exception ("No worry, I will control it");
}
base.Up();
}
public void TurnOffAutoDetect()
{
OffAutoDetection = true;
}
}
Liskov substitution principle
SOLID - TOAN NGUYEN
static void Main(string[] args)
{
var airPlane = new SmartAirePlane ();
var pilot = new Pilot(airPlane);
airPlane.AirPlaneUp = true;
pilot.HandleAirePlane();
}
Benefits of LSP
Avoid unexpected behavior of software
SOLID - TOAN NGUYEN
Avoid violate LSP
1. No easy way to detect the violation
2. Review code
3. Shouldn’t implement stricter validation than implementation of superclass
4. Shouldn’t break superclass behavior
5. Should run test case (unit test) for all subclass instances
SOLID - TOAN NGUYEN
Interface segregation principle
“Many client-specific interfaces are better than one general-purpose interface.”
Similar??
SRP
SOLID - TOAN NGUYEN
Interface segregation principle
public interface IEmailService
{
void SendEmail(EmailData emailData);
}
SOLID - TOAN NGUYEN
public class GraphEmailService : IEmailService
{
dynamic graph = new { };
public void SendEmail(EmailData emailData)
{
var email = new
{
from = emailData.From,
to = emailData.To,
message = emailData.Message
};
graph.sendEmail(email);
}
}
public class SendGridEmailService : IEmailService
{
dynamic sendGrid = new { };
public void SendEmail(EmailData emailData)
{
var email = new
{
from = emailData.From,
to = emailData.To,
message = emailData.Message
};
sendGrid.sendEmail(email);
}
}
Interface segregation principle
SOLID - TOAN NGUYEN
Interface segregation principle
SOLID - TOAN NGUYEN
Benefits of ISP
Similar Single responsibility
SOLID - TOAN NGUYEN
Avoid violate ISP
1. Large interface (flat interface)
2. throw new NotImplementedException();
SOLID - TOAN NGUYEN
Dependency inversion principle
1. High-level modules should not depend on low-level modules. Both should depend on
abstractions.
2. Abstractions should not depend on details. Details should depend on abstractions.
Related to???
OCP & LSP
SOLID - TOAN NGUYEN
Benefits of DIP
Decoupling between
1. Abstractions and details
2. High level and low level
SOLID - TOAN NGUYEN
Distinguish between DIP, IoC and DI
1. DIP: Dependency inversion principle is about decoupling
2. IoC: Inversion of control is a design principle used by framework libraries that allow the
framework to regain and instance of class during program execution. Or could be referred by
"Hollywood Principle: Don't call us, we'll call you"
3. DI: Dependency Injection is an implementation of IoC. Another implementation of IoC is
service locator
SOLID - TOAN NGUYEN
Q&A
SOLID - TOAN NGUYEN
Thanks you!
SOLID - TOAN NGUYEN

Solid principles

  • 1.
    SOLID Principles Every developer shouldknow TOAN NGUYEN TO A N - H U U . N G U Y E N @ KO L E K TO . N L NGUYENTOANUIT
  • 2.
    Agenda What are SOLID? Whyshould we care? How can we apply SOLID principles? ◦ S – Single responsibility principle ◦ O – Open–closed principle ◦ L – Liskov substitution principle ◦ I – Interface segregation principle ◦ D – Dependency inversion principle SOLID - TOAN NGUYEN
  • 3.
    About me Nguyen HuuToan Senior Dev – skype nguyentoanuit@gmail.com SWGLayer team https://app.kolekto.nl SOLID - TOAN NGUYEN
  • 4.
    What is SOLID? “Itis not enough for code to work.” - Robert C. Martin SOLID is five basic principles which help us write clean code ◦ Understandable ◦ Easier to maintain ◦ Easier to extend The abbreviation SOLID was introduced by Michael Feathers But the concept of SOLID principles were first introduced by Robert C. Martin in his book, Design Principles and Design Patterns. So let see how SOLID can help us be stronger SOLID - TOAN NGUYEN
  • 5.
    Why should we care? BUTWAIT A MINUTE!!! WHY SHOULD WE NEED TO APPLY IT? SOLID - TOAN NGUYEN
  • 6.
    Why should wecare? Can we just make it work without following these principles? Finish the business rules/PBI and delivery functionality to client are our main task, why do we need to care about these annoying rules/principles? SOLID - TOAN NGUYEN
  • 7.
    Why should wecare? Yes, of-course. BUT..... the functionality that you create today has a good chance of changing in the next release. The more you care about good code today, the more you are loved by your teammate later SOLID - TOAN NGUYEN
  • 8.
    Why should wecare? So I will make it work first and refactor later on? SOLID - TOAN NGUYEN
  • 9.
    Why should wecare? Yes, sure! But it will be very expensive. SOLID - TOAN NGUYEN
  • 10.
    Why should wecare? “People will forget how fast you did a job, but they remember how well you did it!” - iDev SOLID - TOAN NGUYEN
  • 11.
    How can we applySOLID principles? S – Single responsibility principle (SRP) O – Open–closed principle (OCP) L – Liskov substitution principle (LSP) I – Interface segregation principle (ISP) D – Dependency inversion principle (DIP) SOLID - TOAN NGUYEN
  • 12.
    S – Singleresponsibility principle “A class should only have a single responsibility” So that, a class should have one and only one reason to change. SOLID - TOAN NGUYEN
  • 13.
    S – Singleresponsibility principle public class Production { public Guid Id { get; set; } public string Title { get; set; } public string ShortDescription { get; set; } public string ImageUrl { get; set; } public int RemainItems { get; set; } public string CheckStatus() { if (RemainItems > 500) { return "There are a lot of remaining items"; } else if (RemainItems <= 500 && RemainItems > 200) { return "Warning: We should buy more"; } else { return "Red warning: We need by more"; } } } SOLID - TOAN NGUYEN Inventory business
  • 14.
    S – Singleresponsibility principle public void SendEmail(EmailData emailData) { var email = new { from = emailData.From, to = emailData.To, message = emailData.Message }; graph.sendEmail(email); } SOLID - TOAN NGUYEN
  • 15.
    S – Singleresponsibility principle SOLID - TOAN NGUYEN public void SendEmail(EmailData emailData, bool generateAttachment) { var email = new GraphEmail { from = emailData.From, to = emailData.To, message = emailData.Message }; if (generateAttachment) { var document = new { title = emailData.AttachmentName, content = pdfGenerator.GeneratePDF(emailData.Message) }; email.attachment = document; } graph.sendEmail(email); } Generate attachment is not a job of send email function
  • 16.
    Avoid violate SRP 1.Long method 2. Boolean flag 3. Class (service) serve many operations 4. Always ask why is the responsibility of class/service/module when extending SOLID - TOAN NGUYEN
  • 17.
    Benefits of SRP 1.Easy to follow/understand 2. Maintainable 3. Test easily 4. Easy to extend SOLID - TOAN NGUYEN
  • 18.
    Open–closed principle Entities shouldbe open for extension, but closed for modification. SOLID - TOAN NGUYEN
  • 19.
  • 20.
  • 21.
    Open–closed principle SOLID -TOAN NGUYEN User form
  • 22.
    Open–closed principle SOLID -TOAN NGUYEN Is it fully follow OCP?
  • 23.
    Open–closed principle As applicationgrow up, a lot of new behaviors of the form will be added such as ◦ Handle dirty form ◦ Confirmed/warning message ◦ User only can view data, can’t make a change in the form ◦ Show overlay when data is loading ◦ more and more ….. SOLID - TOAN NGUYEN
  • 24.
  • 25.
    Open–closed principle Composition insteadof inheritance SOLID - TOAN NGUYEN <form> <FormContext.Provider value={setupContextForm()}> <Header /> <DirtyCheck /> <BaseWarningMessage /> <ConfirmMessage /> <Messages /> <BaseValidation /> <UserFormFields /> <FormButtons /> .... </FormContext.Provider> </form>
  • 26.
    Benefits of OCP 1.Reusable and maintainable 2. Avoid regression bugs 3. Extend easily and quickly SOLID - TOAN NGUYEN
  • 27.
    Avoid violate OCP 1.Using inheritance 2. Using Composition 3. Using interface SOLID - TOAN NGUYEN
  • 28.
    Liskov substitution principle LetΦ(x) be a property provable about objects x of type T. Then Φ(y)should be true for objects y of type S where S is a subtype of T. Developer language "Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.“ Related to??? Open – close principle SOLID - TOAN NGUYEN
  • 29.
    Liskov substitution principle SOLID- TOAN NGUYEN public class Airplane { public string Name { get; set; } public virtual void TakeOff() { Console.WriteLine("Hello madam and gentleman, we are taking off"); } public virtual void Landdown() { Console.WriteLine("Hello madam and gentleman, we are landing"); } public virtual void Up() { Console.WriteLine("Air plane go up"); } public virtual void Down() { Console.WriteLine("Air plane go down"); } } public class TraditionalAirPlane : Airplane { public TraditionalAirPlane() { Name = “Traditional one"; } }
  • 30.
    Liskov substitution principle SOLID- TOAN NGUYEN static void Main(string[] args) { var airPlane = new BoeingB52(); var pilot = new Pilot(airPlane); pilot.HandleAirePlane(); }
  • 31.
    Liskov substitution principle SOLID- TOAN NGUYEN public class SmartAirplane : Airplane { public bool AirPlaneUp { get; set; } public bool OffAutoDetection { get; set; } public SmartAirplane() { Name = "I am smart air plane" ; } public override void Up() { if (AirPlaneUp && !OffAutoDetection) { throw new System. Exception ("No worry, I will control it"); } base.Up(); } public void TurnOffAutoDetect() { OffAutoDetection = true; } }
  • 32.
    Liskov substitution principle SOLID- TOAN NGUYEN static void Main(string[] args) { var airPlane = new SmartAirePlane (); var pilot = new Pilot(airPlane); airPlane.AirPlaneUp = true; pilot.HandleAirePlane(); }
  • 33.
    Benefits of LSP Avoidunexpected behavior of software SOLID - TOAN NGUYEN
  • 34.
    Avoid violate LSP 1.No easy way to detect the violation 2. Review code 3. Shouldn’t implement stricter validation than implementation of superclass 4. Shouldn’t break superclass behavior 5. Should run test case (unit test) for all subclass instances SOLID - TOAN NGUYEN
  • 35.
    Interface segregation principle “Manyclient-specific interfaces are better than one general-purpose interface.” Similar?? SRP SOLID - TOAN NGUYEN
  • 36.
    Interface segregation principle publicinterface IEmailService { void SendEmail(EmailData emailData); } SOLID - TOAN NGUYEN public class GraphEmailService : IEmailService { dynamic graph = new { }; public void SendEmail(EmailData emailData) { var email = new { from = emailData.From, to = emailData.To, message = emailData.Message }; graph.sendEmail(email); } } public class SendGridEmailService : IEmailService { dynamic sendGrid = new { }; public void SendEmail(EmailData emailData) { var email = new { from = emailData.From, to = emailData.To, message = emailData.Message }; sendGrid.sendEmail(email); } }
  • 37.
  • 38.
  • 39.
    Benefits of ISP SimilarSingle responsibility SOLID - TOAN NGUYEN
  • 40.
    Avoid violate ISP 1.Large interface (flat interface) 2. throw new NotImplementedException(); SOLID - TOAN NGUYEN
  • 41.
    Dependency inversion principle 1.High-level modules should not depend on low-level modules. Both should depend on abstractions. 2. Abstractions should not depend on details. Details should depend on abstractions. Related to??? OCP & LSP SOLID - TOAN NGUYEN
  • 42.
    Benefits of DIP Decouplingbetween 1. Abstractions and details 2. High level and low level SOLID - TOAN NGUYEN
  • 43.
    Distinguish between DIP,IoC and DI 1. DIP: Dependency inversion principle is about decoupling 2. IoC: Inversion of control is a design principle used by framework libraries that allow the framework to regain and instance of class during program execution. Or could be referred by "Hollywood Principle: Don't call us, we'll call you" 3. DI: Dependency Injection is an implementation of IoC. Another implementation of IoC is service locator SOLID - TOAN NGUYEN
  • 44.
  • 45.

Editor's Notes

  • #13  It doesn't mean that a class should have one property and one method. All the methods and properties should all work towards the same goal
  • #14 Later, we need to check status of a production to decide buy more or not
  • #15 Later we want to support send email with attachment
  • #20 We have base form like this
  • #22 So we can add more form like product, invoice without changing base form
  • #26 How can se communicate between these components? => Pub/Sub pattern
  • #28 Why we have interface here? If you think of application level, for example your application need support send email 1. we will implement email service which use graph api for example, 2. later we also need to support SendGrid as send mail service as well. So by implement interface IEmailService we can extend application easily by don’t modify the service using graph api.
  • #29 A company’s broken this rule and get a very big problem now. => Boeing
  • #40 Easy to follow/understand Maintainable Test easily
  • #42 The Open/Closed Principle required a software component to be open for extension, but closed for modification. You can achieve that by introducing interfaces for which you can provide different implementations. The interface itself is closed for modification, and you can easily extend it by providing a new interface implementation. Your implementations should follow the Liskov Substitution Principle so that you can replace them with other implementations of the same interface without breaking your application.
  • #43 Test easily