SlideShare una empresa de Scribd logo
1 de 35
SOLID Principles
   Declan Whelan
     @dwhelan
SOLID Principles

• Single Responsibility Principle
• Open Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
Single Responsibility
        Principle


There should be one and only one
reason for a class to change.
SRP Violation
public class UserSettingService
{
  public void changeEmail(User user)
  {
    if(checkAccess(user))
    {
       //Grant option to change
    }
  }

  public boolean checkAccess(User user)
  {
    //Verify if the user is valid.
  }
}
SRP Restored
public class UserSettingService
{
  public void changeEmail(User user)
  {
    if(SecurityService.checkAccess(user))
    {
       //Grant option to change
    }
  }
}

public class SecurityService
{
  public static boolean checkAccess(User user)
  {
    //check the access.
  }
}
Open Closed Principle


Software entities should be open for
extension but closed for modification.
A Product Filter


We need a way to filter products by colour.
Class Responsibility
The classes’ responsibility is to filter
products (its job) based off the action of
filtering by colour (its behaviour).
The ProductFilter is responsible for
filtering products by colour.
Filter By Colour
public class ProductFilter
{
  public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor)
  {
     foreach (var product in products)
     {
        if (product.Color == productColor)
            yield return product;
     }
  }
}
More Requirements!
User: We also need to filter by size.
Developer: Just size or colour and size?
User: Umm probably both.
Developer: Great!
Filter By Colour

The ProductFilter is responsible
for filtering products by colour,
size, colour and size.
public class ProductFilter
{

  {
                        Filter By Colour
  public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor)

     foreach (var product in products)
     {
        if (product.Color == productColor)
            yield return product;
     }
  }

    public IEnumerable<Product> ByColorAndSize(IList<Product> products,
                                   ProductColor productColor,
                                   ProductSize productSize)
    {
      foreach (var product in products)
      {
         if ((product.Color == productColor) &&
             (product.Size == productSize))
             yield return product;
      }
    }

    public IEnumerable<Product> BySize(IList<Product> products,
                             ProductSize productSize)
    {
      foreach (var product in products)
      {
         if ((product.Size == productSize))
             yield return product;
      }
    }
}
OCP Filter
     public abstract class ProductFilterSpecification
{
    public IEnumerable<Product> Filter(IList<Product> products)
    {
      return ApplyFilter(products);
    }

    protected abstract IEnumerable<Product> ApplyFilter(IList<Product> products);
}

public class ProductFilter
{
  public IEnumerable<Product> By(IList<Product> products, ProductFilterSpecification
                                        filterSpecification)
  {
     return filterSpecification.Filter(products);
  }
}
OCP Filter
     public class ColorFilterSpecification : ProductFilterSpecification
{
    private readonly ProductColor productColor;

    public ColorFilterSpecification(ProductColor productColor)
    {
      this.productColor = productColor;
    }

    protected override IEnumerable<Product> ApplyFilter(IList<Product> products)
    {
      foreach (var product in products)
      {
         if (product.Color == productColor)
             yield return product;
      }
    }
}
Liskov Substitution
         Principle

Functions that use references to base
classes must be able to use objects of
derived classes without knowing it.
LSP Violation
    class Rectangle
{
!   protected int m_width;
!   protected int m_height;

!   public void setWidth(int width){
!   ! m_width = width;
!   }

!   public void setHeight(int height){
!   ! m_height = height;
!   }

!   public int getWidth(){
!   ! return m_width;
!   }

!   public int getHeight(){
!   ! return m_height;
!   }

!   public int getArea(){
!   ! return m_width * m_height;
!   }!
}
LSP Violation
    class Square extends Rectangle
{
!   public void setWidth(int width){
!   ! m_width = width;
!   ! m_height = width;
!   }

!   public void setHeight(int height){
!   ! m_width = height;
!   ! m_height = height;
!   }
}
LSP Violation
    class LspTest
{
!   private static Rectangle getNewRectangle()
!   {
!   ! // it can be an object returned by some factory ...
!   ! return new Square();
!   }

!   public static void main (String args[])
!   {
!   ! Rectangle r = LspTest.getNewRectangle();

!   !   r.setWidth(5);
!   !   r.setHeight(10);
!   !   // user knows that r it's a rectangle.
!   !   // It assumes that he's able to set the width and height as for the base class

!   !   System.out.println(r.getArea());
!   !   // now he's surprised to see that the area is 100 instead of 50.
!   }
}
Interface Segregation
         Principle


Clients should not be forced to depend
on interfaces that they do not use.
ISP Example
    public abstract class Animal
{
    public abstract void Feed();
}

public class Dog : Animal
{
  public override void Feed()
  {
     // do something
  }
}

public class Rattlesnake : Animal
{
  public override void Feed()
  {
     // do something
  }
}
ISP Violation
    public abstract class Animal
{
    public abstract void Feed();
    public abstract void Groom();
}

public class Rattlesnake : Animal
{
  public override void Feed()
  {
     // do something
  }

    public override void Groom()
    {
      // ignore
    }
}
ISP Restored
     public interface IPet
{
    void Groom();
}

public abstract class Animal
{
  public abstract void Feed();
}

public class Dog : Animal, IPet
{
  public override void Feed()
  {
     // do something
  }

    public void Groom()
    {
      // do something
    }
}

public class Rattlesnake : Animal
{
  public override void Feed()
  {
     // do something
  }
Handout
public class CustomMembershipProvider : MembershipProvider
{
  public override string ApplicationName
  {
     get
     {
        throw new Exception("The method or operation is not implemented.");
     }
     set
     {
        throw new Exception("The method or operation is not implemented.");
     }
  }

  public override bool ChangePassword(string username, string oldPassword, string
newPassword)
  {
    throw new Exception("The method or operation is not implemented.");
  }

  public override bool ChangePasswordQuestionAndAnswer(string username, string
Dependency Inversion
      Principle
High level modules should not depend
upon low level modules. Both should
depend upon abstractions.
Abstractions should not depend upon
details. Details should depend upon
abstractions.
DIP Violation
    public class OrderProcessor
{
    public decimal CalculateTotal(Order order)
    {
        decimal itemTotal = order.GetItemTotal();
        decimal discountAmount = DiscountCalculator.CalculateDiscount(order);

        decimal taxAmount = 0.0M;

        if (order.Country == "US")
            taxAmount = FindTaxAmount(order);
        else if (order.Country == "UK")
            taxAmount = FindVatAmount(order);

        decimal total = itemTotal - discountAmount + taxAmount;

        return total;
    }

    private decimal FindVatAmount(Order order)
    {
        // find the UK value added tax somehow
        return 10.0M;
    }

    private decimal FindTaxAmount(Order order)
    {
        // find the US tax somehow
        return 10.0M;
    }
}
DIP Restored
    public interface IDiscountCalculator
{
    decimal CalculateDiscount(Order order);
}

public interface ITaxStrategy
{
    decimal FindTaxAmount(Order order);
}

public class OrderProcessor
{
    private readonly IDiscountCalculator _discountCalculator;
    private readonly ITaxStrategy _taxStrategy;

    public OrderProcessor(IDiscountCalculator discountCalculator,
                          ITaxStrategy taxStrategy)
    {
        _taxStrategy = taxStrategy;
        _discountCalculator = discountCalculator;
    }

    public decimal CalculateTotal(Order order)
    {
        decimal itemTotal = order.GetItemTotal();
        decimal discountAmount = _discountCalculator.CalculateDiscount(order);
        decimal taxAmount = _taxStrategy.FindTaxAmount(order);
        decimal total = itemTotal - discountAmount + taxAmount;

        return total;
    }
}
DIP Restored
    public class DiscountCalculatorAdapter : IDiscountCalculator
{
    public decimal CalculateDiscount(Order order)
    {
        return DiscountCalculator.CalculateDiscount(order);
    }
}

public class USTaxStrategy : ITaxStrategy
{
    public decimal FindTaxAmount(Order order)
    {
    }
}

public class UKTaxStrategy : ITaxStrategy
{
    public decimal FindTaxAmount(Order order)
    {
    }
}
Reading
Clean Code: A Handbook of Agile Software
Craftsmanship Robert C. Martin

Design Patterns: Elements of Reusable Object-Oriented
Software Erich Gamma, Richard Helm, Ralph Johnson,
and John Vlissides

Agile Principles, Patterns and Practices in C#
Robert C. Martin

Lean Architecture: for Agile Software Development
James O. Coplien and Gertrud Bjørnvig
Photo Credits
SOLID Motivational Posters, by Derick Bailey, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.



                        http://lostechies.com/derickbailey/files/2011/03/SOLID_6EC97F9C.jpg




                        http://lostechies.com/derickbailey/files/2011/03/SingleResponsibilityPrinciple2_71060858.jpg




                        http://lostechies.com/derickbailey/files/2011/03/OpenClosedPrinciple2_2C596E17.jpg




                        http://lostechies.com/derickbailey/files/2011/03/LiskovSubtitutionPrinciple_52BB5162.jpg




                        http://lostechies.com/derickbailey/files/2011/03/InterfaceSegregationPrinciple_60216468.jpg




                        http://lostechies.com/derickbailey/files/2011/03/DependencyInversionPrinciple_0278F9E2.jpg

Más contenido relacionado

La actualidad más candente

Solid design principles
Solid design principlesSolid design principles
Solid design principlesMahmoud Asadi
 
Learning solid principles using c#
Learning solid principles using c#Learning solid principles using c#
Learning solid principles using c#Aditya Kumar Rajan
 
principles of object oriented class design
principles of object oriented class designprinciples of object oriented class design
principles of object oriented class designNeetu Mishra
 
S.O.L.I.D. Principles for Software Architects
S.O.L.I.D. Principles for Software ArchitectsS.O.L.I.D. Principles for Software Architects
S.O.L.I.D. Principles for Software ArchitectsRicardo Wilkins
 
Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesBruno Bossola
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility PrincipleEyal Golan
 
Introducing Clean Architecture
Introducing Clean ArchitectureIntroducing Clean Architecture
Introducing Clean ArchitectureRoc Boronat
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionKnoldus Inc.
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean ArchitectureBadoo
 
The Single Responsibility Principle
The Single Responsibility PrincipleThe Single Responsibility Principle
The Single Responsibility PrincipleLars-Erik Kindblad
 
Refactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesRefactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesSteven Smith
 
Object Oriented Design SOLID Principles
Object Oriented Design SOLID PrinciplesObject Oriented Design SOLID Principles
Object Oriented Design SOLID Principlesrainynovember12
 

La actualidad más candente (20)

Solid principles
Solid principlesSolid principles
Solid principles
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Clean code: SOLID
Clean code: SOLIDClean code: SOLID
Clean code: SOLID
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Solid design principles
Solid design principlesSolid design principles
Solid design principles
 
Learning solid principles using c#
Learning solid principles using c#Learning solid principles using c#
Learning solid principles using c#
 
Solid Principles
Solid PrinciplesSolid Principles
Solid Principles
 
principles of object oriented class design
principles of object oriented class designprinciples of object oriented class design
principles of object oriented class design
 
SOLID
SOLIDSOLID
SOLID
 
S.O.L.I.D. Principles for Software Architects
S.O.L.I.D. Principles for Software ArchitectsS.O.L.I.D. Principles for Software Architects
S.O.L.I.D. Principles for Software Architects
 
Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design Principles
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility Principle
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Introducing Clean Architecture
Introducing Clean ArchitectureIntroducing Clean Architecture
Introducing Clean Architecture
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test Automaion
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
The Single Responsibility Principle
The Single Responsibility PrincipleThe Single Responsibility Principle
The Single Responsibility Principle
 
Refactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesRefactoring Applications using SOLID Principles
Refactoring Applications using SOLID Principles
 
Object Oriented Design SOLID Principles
Object Oriented Design SOLID PrinciplesObject Oriented Design SOLID Principles
Object Oriented Design SOLID Principles
 

Destacado

SOLID Principles Part 2
SOLID Principles Part 2SOLID Principles Part 2
SOLID Principles Part 2Maulik Soni
 
Sa 006 modifiability
Sa 006 modifiabilitySa 006 modifiability
Sa 006 modifiabilityFrank Gielen
 
Success by Challenging Assumptions (Part 2)
Success by Challenging Assumptions (Part 2)Success by Challenging Assumptions (Part 2)
Success by Challenging Assumptions (Part 2)LaDonna Coy
 
Make yourself replaceable at DevOpsCon 2016 Berlin
Make yourself replaceable at DevOpsCon 2016 BerlinMake yourself replaceable at DevOpsCon 2016 Berlin
Make yourself replaceable at DevOpsCon 2016 BerlinErno Aapa
 
SOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User GroupSOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User GroupAdnan Masood
 
Success by Challenging Assumptions (Part I)
Success by Challenging Assumptions (Part I)Success by Challenging Assumptions (Part I)
Success by Challenging Assumptions (Part I)LaDonna Coy
 
The SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design PatternsThe SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design PatternsHayim Makabee
 
SOLID Principles and Design Patterns
SOLID Principles and Design PatternsSOLID Principles and Design Patterns
SOLID Principles and Design PatternsGanesh Samarthyam
 
Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHPSteve Rhoades
 
Aggregates, Entities and Value objects - Devnology 2010 community day
Aggregates, Entities and Value objects - Devnology 2010 community dayAggregates, Entities and Value objects - Devnology 2010 community day
Aggregates, Entities and Value objects - Devnology 2010 community dayRick van der Arend
 
Design Thinking is Killing Creativity
Design Thinking is Killing CreativityDesign Thinking is Killing Creativity
Design Thinking is Killing Creativitydesignsojourn
 

Destacado (14)

SOLID Principles Part 2
SOLID Principles Part 2SOLID Principles Part 2
SOLID Principles Part 2
 
Sa 006 modifiability
Sa 006 modifiabilitySa 006 modifiability
Sa 006 modifiability
 
Success by Challenging Assumptions (Part 2)
Success by Challenging Assumptions (Part 2)Success by Challenging Assumptions (Part 2)
Success by Challenging Assumptions (Part 2)
 
Make yourself replaceable at DevOpsCon 2016 Berlin
Make yourself replaceable at DevOpsCon 2016 BerlinMake yourself replaceable at DevOpsCon 2016 Berlin
Make yourself replaceable at DevOpsCon 2016 Berlin
 
SOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User GroupSOLID Principles of Refactoring Presentation - Inland Empire User Group
SOLID Principles of Refactoring Presentation - Inland Empire User Group
 
Success by Challenging Assumptions (Part I)
Success by Challenging Assumptions (Part I)Success by Challenging Assumptions (Part I)
Success by Challenging Assumptions (Part I)
 
SOLID Principles part 2
SOLID Principles part 2SOLID Principles part 2
SOLID Principles part 2
 
SOLID Principles part 1
SOLID Principles part 1SOLID Principles part 1
SOLID Principles part 1
 
The SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design PatternsThe SOLID Principles Illustrated by Design Patterns
The SOLID Principles Illustrated by Design Patterns
 
SOLID Principles and Design Patterns
SOLID Principles and Design PatternsSOLID Principles and Design Patterns
SOLID Principles and Design Patterns
 
Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHP
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Aggregates, Entities and Value objects - Devnology 2010 community day
Aggregates, Entities and Value objects - Devnology 2010 community dayAggregates, Entities and Value objects - Devnology 2010 community day
Aggregates, Entities and Value objects - Devnology 2010 community day
 
Design Thinking is Killing Creativity
Design Thinking is Killing CreativityDesign Thinking is Killing Creativity
Design Thinking is Killing Creativity
 

Similar a SOLID Principles Explained

Solid Software Design Principles
Solid Software Design PrinciplesSolid Software Design Principles
Solid Software Design PrinciplesJon Kruger
 
CodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigCodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigDusan Zamurovic
 
Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Antoine Sabot-Durand
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCaelum
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEDarwin Durand
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design PatternsGodfrey Nolan
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietyChris Weldon
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIsDmitry Buzdin
 
1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-DurandSOAT
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в JavaDEVTYPE
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!DataArt
 
1 MVC – Ajax and Modal Views AJAX stands for Asynch.docx
1  MVC – Ajax and Modal Views AJAX stands for Asynch.docx1  MVC – Ajax and Modal Views AJAX stands for Asynch.docx
1 MVC – Ajax and Modal Views AJAX stands for Asynch.docxhoney725342
 
Design patterns in the 21st Century
Design patterns in the 21st CenturyDesign patterns in the 21st Century
Design patterns in the 21st CenturySamir Talwar
 
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Constanța Developers
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехСбертех | SberTech
 

Similar a SOLID Principles Explained (20)

SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
DotNet Conference: code smells
DotNet Conference: code smellsDotNet Conference: code smells
DotNet Conference: code smells
 
Solid Software Design Principles
Solid Software Design PrinciplesSolid Software Design Principles
Solid Software Design Principles
 
CodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigCodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPig
 
Functional Programming with C#
Functional Programming with C#Functional Programming with C#
Functional Programming with C#
 
Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptor
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design Patterns
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
 
1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand1/3 : introduction to CDI - Antoine Sabot-Durand
1/3 : introduction to CDI - Antoine Sabot-Durand
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
1 MVC – Ajax and Modal Views AJAX stands for Asynch.docx
1  MVC – Ajax and Modal Views AJAX stands for Asynch.docx1  MVC – Ajax and Modal Views AJAX stands for Asynch.docx
1 MVC – Ajax and Modal Views AJAX stands for Asynch.docx
 
Design patterns in the 21st Century
Design patterns in the 21st CenturyDesign patterns in the 21st Century
Design patterns in the 21st Century
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
Andrei Iacob - SOLID: Strategies for Implementing Object–Oriented Design Prin...
 
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
 

Más de Declan Whelan

Technical debt is a systemic problem - not a personal failing
Technical debt is a systemic problem - not a personal failingTechnical debt is a systemic problem - not a personal failing
Technical debt is a systemic problem - not a personal failingDeclan Whelan
 
From Technical Debt to Technical Health
From Technical Debt to Technical HealthFrom Technical Debt to Technical Health
From Technical Debt to Technical HealthDeclan Whelan
 
effective agile adoption
effective agile adoptioneffective agile adoption
effective agile adoptionDeclan Whelan
 
Navigating Organizational Change
Navigating Organizational ChangeNavigating Organizational Change
Navigating Organizational ChangeDeclan Whelan
 
Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDeclan Whelan
 
Win Win Conversations
Win Win ConversationsWin Win Conversations
Win Win ConversationsDeclan Whelan
 
Agile 2012 Simple Design Applied
Agile 2012 Simple Design AppliedAgile 2012 Simple Design Applied
Agile 2012 Simple Design AppliedDeclan Whelan
 
Releasing your teams energy through 'pull' conversations
Releasing your teams energy through 'pull' conversationsReleasing your teams energy through 'pull' conversations
Releasing your teams energy through 'pull' conversationsDeclan Whelan
 
Specification by Example
Specification by ExampleSpecification by Example
Specification by ExampleDeclan Whelan
 
Learning is Key to Agile Success: Agile Vancouver 2010
Learning is Key to Agile Success: Agile Vancouver 2010Learning is Key to Agile Success: Agile Vancouver 2010
Learning is Key to Agile Success: Agile Vancouver 2010Declan Whelan
 
Agile learning agile 2010
Agile learning agile 2010Agile learning agile 2010
Agile learning agile 2010Declan Whelan
 
Agile Learning (60 minute version)
Agile Learning (60 minute version)Agile Learning (60 minute version)
Agile Learning (60 minute version)Declan Whelan
 
Agile Learning from Agile 2009
Agile Learning from Agile 2009Agile Learning from Agile 2009
Agile Learning from Agile 2009Declan Whelan
 
Agile Testing: The Role Of The Agile Tester
Agile Testing: The Role Of The Agile TesterAgile Testing: The Role Of The Agile Tester
Agile Testing: The Role Of The Agile TesterDeclan Whelan
 

Más de Declan Whelan (18)

Technical debt is a systemic problem - not a personal failing
Technical debt is a systemic problem - not a personal failingTechnical debt is a systemic problem - not a personal failing
Technical debt is a systemic problem - not a personal failing
 
From Technical Debt to Technical Health
From Technical Debt to Technical HealthFrom Technical Debt to Technical Health
From Technical Debt to Technical Health
 
effective agile adoption
effective agile adoptioneffective agile adoption
effective agile adoption
 
Big Balls of Mud
Big Balls of MudBig Balls of Mud
Big Balls of Mud
 
Navigating Organizational Change
Navigating Organizational ChangeNavigating Organizational Change
Navigating Organizational Change
 
Simple Design
Simple DesignSimple Design
Simple Design
 
Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with Rails
 
Win Win Conversations
Win Win ConversationsWin Win Conversations
Win Win Conversations
 
Agile 2012 Simple Design Applied
Agile 2012 Simple Design AppliedAgile 2012 Simple Design Applied
Agile 2012 Simple Design Applied
 
Releasing your teams energy through 'pull' conversations
Releasing your teams energy through 'pull' conversationsReleasing your teams energy through 'pull' conversations
Releasing your teams energy through 'pull' conversations
 
Specification by Example
Specification by ExampleSpecification by Example
Specification by Example
 
Learning is Key to Agile Success: Agile Vancouver 2010
Learning is Key to Agile Success: Agile Vancouver 2010Learning is Key to Agile Success: Agile Vancouver 2010
Learning is Key to Agile Success: Agile Vancouver 2010
 
Agile learning agile 2010
Agile learning agile 2010Agile learning agile 2010
Agile learning agile 2010
 
Agile Learning (60 minute version)
Agile Learning (60 minute version)Agile Learning (60 minute version)
Agile Learning (60 minute version)
 
Cuke2Beer
Cuke2BeerCuke2Beer
Cuke2Beer
 
Agile Learning from Agile 2009
Agile Learning from Agile 2009Agile Learning from Agile 2009
Agile Learning from Agile 2009
 
Agile, Tdd And .Net
Agile, Tdd And .NetAgile, Tdd And .Net
Agile, Tdd And .Net
 
Agile Testing: The Role Of The Agile Tester
Agile Testing: The Role Of The Agile TesterAgile Testing: The Role Of The Agile Tester
Agile Testing: The Role Of The Agile Tester
 

Último

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 

Último (20)

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 

SOLID Principles Explained

  • 1. SOLID Principles Declan Whelan @dwhelan
  • 2.
  • 3. SOLID Principles • Single Responsibility Principle • Open Closed Principle • Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
  • 4.
  • 5. Single Responsibility Principle There should be one and only one reason for a class to change.
  • 6. SRP Violation public class UserSettingService {   public void changeEmail(User user)   {     if(checkAccess(user))     {        //Grant option to change     }   }   public boolean checkAccess(User user)   {     //Verify if the user is valid.   } }
  • 7. SRP Restored public class UserSettingService {   public void changeEmail(User user)   {     if(SecurityService.checkAccess(user))     {        //Grant option to change     }   } } public class SecurityService {   public static boolean checkAccess(User user)   {     //check the access.   } }
  • 8.
  • 9. Open Closed Principle Software entities should be open for extension but closed for modification.
  • 10. A Product Filter We need a way to filter products by colour.
  • 11. Class Responsibility The classes’ responsibility is to filter products (its job) based off the action of filtering by colour (its behaviour). The ProductFilter is responsible for filtering products by colour.
  • 12. Filter By Colour public class ProductFilter { public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor) { foreach (var product in products) { if (product.Color == productColor) yield return product; } } }
  • 13. More Requirements! User: We also need to filter by size. Developer: Just size or colour and size? User: Umm probably both. Developer: Great!
  • 14. Filter By Colour The ProductFilter is responsible for filtering products by colour, size, colour and size.
  • 15. public class ProductFilter { { Filter By Colour public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor) foreach (var product in products) { if (product.Color == productColor) yield return product; } } public IEnumerable<Product> ByColorAndSize(IList<Product> products, ProductColor productColor, ProductSize productSize) { foreach (var product in products) { if ((product.Color == productColor) && (product.Size == productSize)) yield return product; } } public IEnumerable<Product> BySize(IList<Product> products, ProductSize productSize) { foreach (var product in products) { if ((product.Size == productSize)) yield return product; } } }
  • 16. OCP Filter public abstract class ProductFilterSpecification { public IEnumerable<Product> Filter(IList<Product> products) { return ApplyFilter(products); } protected abstract IEnumerable<Product> ApplyFilter(IList<Product> products); } public class ProductFilter { public IEnumerable<Product> By(IList<Product> products, ProductFilterSpecification filterSpecification) { return filterSpecification.Filter(products); } }
  • 17. OCP Filter public class ColorFilterSpecification : ProductFilterSpecification { private readonly ProductColor productColor; public ColorFilterSpecification(ProductColor productColor) { this.productColor = productColor; } protected override IEnumerable<Product> ApplyFilter(IList<Product> products) { foreach (var product in products) { if (product.Color == productColor) yield return product; } } }
  • 18.
  • 19. Liskov Substitution Principle Functions that use references to base classes must be able to use objects of derived classes without knowing it.
  • 20. LSP Violation class Rectangle { ! protected int m_width; ! protected int m_height; ! public void setWidth(int width){ ! ! m_width = width; ! } ! public void setHeight(int height){ ! ! m_height = height; ! } ! public int getWidth(){ ! ! return m_width; ! } ! public int getHeight(){ ! ! return m_height; ! } ! public int getArea(){ ! ! return m_width * m_height; ! }! }
  • 21. LSP Violation class Square extends Rectangle { ! public void setWidth(int width){ ! ! m_width = width; ! ! m_height = width; ! } ! public void setHeight(int height){ ! ! m_width = height; ! ! m_height = height; ! } }
  • 22. LSP Violation class LspTest { ! private static Rectangle getNewRectangle() ! { ! ! // it can be an object returned by some factory ... ! ! return new Square(); ! } ! public static void main (String args[]) ! { ! ! Rectangle r = LspTest.getNewRectangle(); ! ! r.setWidth(5); ! ! r.setHeight(10); ! ! // user knows that r it's a rectangle. ! ! // It assumes that he's able to set the width and height as for the base class ! ! System.out.println(r.getArea()); ! ! // now he's surprised to see that the area is 100 instead of 50. ! } }
  • 23.
  • 24. Interface Segregation Principle Clients should not be forced to depend on interfaces that they do not use.
  • 25. ISP Example public abstract class Animal { public abstract void Feed(); } public class Dog : Animal { public override void Feed() { // do something } } public class Rattlesnake : Animal { public override void Feed() { // do something } }
  • 26. ISP Violation public abstract class Animal { public abstract void Feed(); public abstract void Groom(); } public class Rattlesnake : Animal { public override void Feed() { // do something } public override void Groom() { // ignore } }
  • 27. ISP Restored public interface IPet { void Groom(); } public abstract class Animal { public abstract void Feed(); } public class Dog : Animal, IPet { public override void Feed() { // do something } public void Groom() { // do something } } public class Rattlesnake : Animal { public override void Feed() { // do something }
  • 28. Handout public class CustomMembershipProvider : MembershipProvider { public override string ApplicationName { get { throw new Exception("The method or operation is not implemented."); } set { throw new Exception("The method or operation is not implemented."); } } public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new Exception("The method or operation is not implemented."); } public override bool ChangePasswordQuestionAndAnswer(string username, string
  • 29.
  • 30. Dependency Inversion Principle High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
  • 31. DIP Violation public class OrderProcessor { public decimal CalculateTotal(Order order) { decimal itemTotal = order.GetItemTotal(); decimal discountAmount = DiscountCalculator.CalculateDiscount(order); decimal taxAmount = 0.0M; if (order.Country == "US") taxAmount = FindTaxAmount(order); else if (order.Country == "UK") taxAmount = FindVatAmount(order); decimal total = itemTotal - discountAmount + taxAmount; return total; } private decimal FindVatAmount(Order order) { // find the UK value added tax somehow return 10.0M; } private decimal FindTaxAmount(Order order) { // find the US tax somehow return 10.0M; } }
  • 32. DIP Restored public interface IDiscountCalculator { decimal CalculateDiscount(Order order); } public interface ITaxStrategy { decimal FindTaxAmount(Order order); } public class OrderProcessor { private readonly IDiscountCalculator _discountCalculator; private readonly ITaxStrategy _taxStrategy; public OrderProcessor(IDiscountCalculator discountCalculator, ITaxStrategy taxStrategy) { _taxStrategy = taxStrategy; _discountCalculator = discountCalculator; } public decimal CalculateTotal(Order order) { decimal itemTotal = order.GetItemTotal(); decimal discountAmount = _discountCalculator.CalculateDiscount(order); decimal taxAmount = _taxStrategy.FindTaxAmount(order); decimal total = itemTotal - discountAmount + taxAmount; return total; } }
  • 33. DIP Restored public class DiscountCalculatorAdapter : IDiscountCalculator { public decimal CalculateDiscount(Order order) { return DiscountCalculator.CalculateDiscount(order); } } public class USTaxStrategy : ITaxStrategy { public decimal FindTaxAmount(Order order) { } } public class UKTaxStrategy : ITaxStrategy { public decimal FindTaxAmount(Order order) { } }
  • 34. Reading Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Design Patterns: Elements of Reusable Object-Oriented Software Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Agile Principles, Patterns and Practices in C# Robert C. Martin Lean Architecture: for Agile Software Development James O. Coplien and Gertrud Bjørnvig
  • 35. Photo Credits SOLID Motivational Posters, by Derick Bailey, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License. http://lostechies.com/derickbailey/files/2011/03/SOLID_6EC97F9C.jpg http://lostechies.com/derickbailey/files/2011/03/SingleResponsibilityPrinciple2_71060858.jpg http://lostechies.com/derickbailey/files/2011/03/OpenClosedPrinciple2_2C596E17.jpg http://lostechies.com/derickbailey/files/2011/03/LiskovSubtitutionPrinciple_52BB5162.jpg http://lostechies.com/derickbailey/files/2011/03/InterfaceSegregationPrinciple_60216468.jpg http://lostechies.com/derickbailey/files/2011/03/DependencyInversionPrinciple_0278F9E2.jpg

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n