SlideShare una empresa de Scribd logo
1 de 28
Descargar para leer sin conexión
Principles behind good software design

  IS YOUR CODE SOLID?
nathangloyn
@NathanGloyn
Design Code Release
nathan@gloyn.co.uk
Agenda

 The origin of S.O.L.I.D
 What is S.O.L.I.D?
 Design Smells
 The principles
 S.O.L.I.D code is...
 Summary
 Questions
 Resources
The origin of S.O.L.I.D
 Who is this man?
The origin of S.O.L.I.D
Principles, Patterns, and Practices
                           Published in 2002
                           First book to mention
                            SOLID
                           C# edition published 2005
                           Both books considered
                            seminal works on SOLID
What is S.O.L.I.D?

 Principles about class design
 To be considered, not rules blindly applied
 Made up of acronyms
 Minimise design smells
 Easier to evolve code
Design Smells

 Rigidity
 Fragility
 Immobility
 Viscosity
 Needless Complexity
 Needless Repetition
 Opacity
The principles

 S ingle Responsibility Principle   –>   SRP
   O pen/Closed Principle           –>   OCP
   L iskov Substitution Principle   –>   LSP
   I nterface Segregation Principle –>   ISP
   D ependency Inversion Principle –>    DIP
The principles
   Single Responsibility Principle

    What is the principle?
       A class should have only one reason to change.


    Why should you use it?
       Helps with separation of concerns
       Increases cohesion
       Reduces coupling
       Simplifies the code, making it more readable
       Makes future changes easier
The principles
   Single Responsibility Principle



     Code
The principles
   Interface Segregation Principle

    What is the principle?
       Clients should not be forced to depend upon
        interfaces that they do not use
       Avoid “fat” interfaces
    Why should you use it?
       Reduces coupling
       Implementers only use bits they need.
       Helps reduce dependencies
The principles
   Interface Segregation Principle


     Code
The principles
   Dependency Inversion Principle

    What is the principle?
       High-level modules should not depend on low-
        level modules. Both should depend on
        abstractions.
       Abstractions should not depend upon details.
        Details should depend upon abstractions.
       Don’t call us, we’ll call you
The principles
   Dependency Inversion Principle


     Policy Layer




                    Mechanism Layer




                                      Utility Layer
The principles
   Dependency Inversion Principle

                     Policy Service
     Policy Layer
                       Interface




                                      Mechanism Service
                    Mechanism Layer
                                          Interface




                                         Utility Layer
The principles
   Dependency Inversion Principle

                       Policy Service   Mechanism Service
     Policy Layer
                         Interface          Interface




                    Mechanism Layer




                                         Utility Layer
The principles
   Dependency Inversion Principle

    Why should you use it?
       Reduces coupling
       Makes it easier to reuse classes
       Can make code easier to test
       Use IoC to help implement
The principles
   Dependency Inversion Principle


     Code
The principles
   Open/closed Principle
    What is the principle?
       Software entities
        (classes, modules, functions, etc.) should be open
        for extension but closed for modification.
       Add new code, don’t touch the old code
    Why should you use it?
       Systems easier to change/evolve
       Reduces risk
       Develop and test extensions in isolation
The principles
   Open/closed Principle


     Code
The principles
   Liskov Substitution Principle
    What is the 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.
       Subtypes must be substitutable for their base
        types.
The principles
   Liskov Substitution Principle
    Why should you use it?
       Consistent behaviour
       Reduces coupling
       Makes it easier to evolve code
The principles
   Liskov Substitution Principle

                            Fail
The principles
   Liskov Substitution Principle


     Code
The principles

 S ingle Responsibility Principle         –> SRP
   A class should have only one reason to change.
 O pen/Closed Principle                   –> OCP
   Add new code, don’t touch the old code
 L iskov Substitution Principle           –> LSP
   Subtypes must be substitutable for their base types
 I nterface Segregation Principle –>           ISP
  Avoid “fat” interfaces
 D ependency Inversion Principle –>            DIP
  Don’t call us, we’ll call you
S.O.L.I.D code is...

  Loosely coupled
  Highly cohesive
  Easy to evolve/change
  Testable
Summary

 Not new, been around a while
 Principles not rules
 You decide when to apply
 It should make it easier to evolve code
 Code will be easier to unit test
Questions?
Resources
 Principles Of Ood
 DimeCasts.Net – screen casts on each principle
 Los Techies – series of posts on principles
 Hanselminutes – podcast with Uncle Bob
 Getting a good SOLID start – post by Uncle bob
 Presentation Code – code from the presentation



 nathangloyn                    Design Code Release
 @NathanGloyn                   nathan@gloyn.co.uk

Más contenido relacionado

Similar a Is your code solid

SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionKnoldus Inc.
 
DesignPrinciples-and-DesignPatterns
DesignPrinciples-and-DesignPatternsDesignPrinciples-and-DesignPatterns
DesignPrinciples-and-DesignPatternsBasavaraj Patil
 
Solid OO & Clean Coding is essential to successful Agile development
Solid OO & Clean Coding is essential to successful Agile developmentSolid OO & Clean Coding is essential to successful Agile development
Solid OO & Clean Coding is essential to successful Agile developmentSimon Gould
 
SOLID principles-Present
SOLID principles-PresentSOLID principles-Present
SOLID principles-PresentQuang Nguyen
 
The OO Design Principles
The OO Design PrinciplesThe OO Design Principles
The OO Design PrinciplesSteve Zhang
 
Is your code SOLID enough?
 Is your code SOLID enough? Is your code SOLID enough?
Is your code SOLID enough?SARCCOM
 
Common Design Patterns.pptx
Common Design Patterns.pptxCommon Design Patterns.pptx
Common Design Patterns.pptxfake195786
 
Agile design pattern
Agile design patternAgile design pattern
Agile design patternPoppy Martono
 
Solid design principles
Solid design principlesSolid design principles
Solid design principlesMahmoud Asadi
 
Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesBruno Bossola
 
Daniel leon design principles in the functional world
Daniel leon   design principles in the functional worldDaniel leon   design principles in the functional world
Daniel leon design principles in the functional worldCodecamp Romania
 
Software design principles
Software design principlesSoftware design principles
Software design principlesMd.Mojibul Hoque
 
SOLID design principles in Ruby
SOLID design principles in RubySOLID design principles in Ruby
SOLID design principles in RubyAnil Wadghule
 

Similar a Is your code solid (20)

SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test Automaion
 
DesignPrinciples-and-DesignPatterns
DesignPrinciples-and-DesignPatternsDesignPrinciples-and-DesignPatterns
DesignPrinciples-and-DesignPatterns
 
Solid OO & Clean Coding is essential to successful Agile development
Solid OO & Clean Coding is essential to successful Agile developmentSolid OO & Clean Coding is essential to successful Agile development
Solid OO & Clean Coding is essential to successful Agile development
 
Solid
SolidSolid
Solid
 
Android architecture
Android architectureAndroid architecture
Android architecture
 
SOLID principles-Present
SOLID principles-PresentSOLID principles-Present
SOLID principles-Present
 
The OO Design Principles
The OO Design PrinciplesThe OO Design Principles
The OO Design Principles
 
Is your code SOLID enough?
 Is your code SOLID enough? Is your code SOLID enough?
Is your code SOLID enough?
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Common Design Patterns.pptx
Common Design Patterns.pptxCommon Design Patterns.pptx
Common Design Patterns.pptx
 
Agile design pattern
Agile design patternAgile design pattern
Agile design pattern
 
Solid Principles
Solid PrinciplesSolid Principles
Solid Principles
 
Solid design principles
Solid design principlesSolid design principles
Solid design principles
 
Soild principles
Soild principlesSoild principles
Soild principles
 
Solid
SolidSolid
Solid
 
Geecon09: SOLID Design Principles
Geecon09: SOLID Design PrinciplesGeecon09: SOLID Design Principles
Geecon09: SOLID Design Principles
 
Daniel leon design principles in the functional world
Daniel leon   design principles in the functional worldDaniel leon   design principles in the functional world
Daniel leon design principles in the functional world
 
Software design principles
Software design principlesSoftware design principles
Software design principles
 
SOLID design principles in Ruby
SOLID design principles in RubySOLID design principles in Ruby
SOLID design principles in Ruby
 
Solid principes
Solid principesSolid principes
Solid principes
 

Más de Nathan Gloyn

Microservices - What I've learned after a year building systems
Microservices - What I've learned after a year building systemsMicroservices - What I've learned after a year building systems
Microservices - What I've learned after a year building systemsNathan Gloyn
 
You keep using the word agile, i do not think it means what you think it means
You keep using the word agile, i do not think it means what you think it meansYou keep using the word agile, i do not think it means what you think it means
You keep using the word agile, i do not think it means what you think it meansNathan Gloyn
 
Selenium ui paradigm - DDD North 2
Selenium ui paradigm - DDD North 2Selenium ui paradigm - DDD North 2
Selenium ui paradigm - DDD North 2Nathan Gloyn
 
Inversion of control containers vs handrolled how they compare
Inversion of control containers vs handrolled   how they compareInversion of control containers vs handrolled   how they compare
Inversion of control containers vs handrolled how they compareNathan Gloyn
 
DDD North - Kanban what is it and how can it help
DDD North - Kanban what is it and how can it helpDDD North - Kanban what is it and how can it help
DDD North - Kanban what is it and how can it helpNathan Gloyn
 
You think you know agile
You think you know agileYou think you know agile
You think you know agileNathan Gloyn
 

Más de Nathan Gloyn (7)

Microservices - What I've learned after a year building systems
Microservices - What I've learned after a year building systemsMicroservices - What I've learned after a year building systems
Microservices - What I've learned after a year building systems
 
You keep using the word agile, i do not think it means what you think it means
You keep using the word agile, i do not think it means what you think it meansYou keep using the word agile, i do not think it means what you think it means
You keep using the word agile, i do not think it means what you think it means
 
No backend
No backendNo backend
No backend
 
Selenium ui paradigm - DDD North 2
Selenium ui paradigm - DDD North 2Selenium ui paradigm - DDD North 2
Selenium ui paradigm - DDD North 2
 
Inversion of control containers vs handrolled how they compare
Inversion of control containers vs handrolled   how they compareInversion of control containers vs handrolled   how they compare
Inversion of control containers vs handrolled how they compare
 
DDD North - Kanban what is it and how can it help
DDD North - Kanban what is it and how can it helpDDD North - Kanban what is it and how can it help
DDD North - Kanban what is it and how can it help
 
You think you know agile
You think you know agileYou think you know agile
You think you know agile
 

Último

Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 

Último (20)

Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 

Is your code solid

  • 1. Principles behind good software design IS YOUR CODE SOLID? nathangloyn @NathanGloyn Design Code Release nathan@gloyn.co.uk
  • 2. Agenda  The origin of S.O.L.I.D  What is S.O.L.I.D?  Design Smells  The principles  S.O.L.I.D code is...  Summary  Questions  Resources
  • 3. The origin of S.O.L.I.D Who is this man?
  • 4. The origin of S.O.L.I.D Principles, Patterns, and Practices  Published in 2002  First book to mention SOLID  C# edition published 2005  Both books considered seminal works on SOLID
  • 5. What is S.O.L.I.D?  Principles about class design  To be considered, not rules blindly applied  Made up of acronyms  Minimise design smells  Easier to evolve code
  • 6. Design Smells  Rigidity  Fragility  Immobility  Viscosity  Needless Complexity  Needless Repetition  Opacity
  • 7. The principles  S ingle Responsibility Principle –> SRP  O pen/Closed Principle –> OCP  L iskov Substitution Principle –> LSP  I nterface Segregation Principle –> ISP  D ependency Inversion Principle –> DIP
  • 8. The principles Single Responsibility Principle  What is the principle?  A class should have only one reason to change.  Why should you use it?  Helps with separation of concerns  Increases cohesion  Reduces coupling  Simplifies the code, making it more readable  Makes future changes easier
  • 9. The principles Single Responsibility Principle Code
  • 10. The principles Interface Segregation Principle  What is the principle?  Clients should not be forced to depend upon interfaces that they do not use  Avoid “fat” interfaces  Why should you use it?  Reduces coupling  Implementers only use bits they need.  Helps reduce dependencies
  • 11. The principles Interface Segregation Principle Code
  • 12. The principles Dependency Inversion Principle  What is the principle?  High-level modules should not depend on low- level modules. Both should depend on abstractions.  Abstractions should not depend upon details. Details should depend upon abstractions.  Don’t call us, we’ll call you
  • 13. The principles Dependency Inversion Principle Policy Layer Mechanism Layer Utility Layer
  • 14. The principles Dependency Inversion Principle Policy Service Policy Layer Interface Mechanism Service Mechanism Layer Interface Utility Layer
  • 15. The principles Dependency Inversion Principle Policy Service Mechanism Service Policy Layer Interface Interface Mechanism Layer Utility Layer
  • 16. The principles Dependency Inversion Principle  Why should you use it?  Reduces coupling  Makes it easier to reuse classes  Can make code easier to test  Use IoC to help implement
  • 17. The principles Dependency Inversion Principle Code
  • 18. The principles Open/closed Principle  What is the principle?  Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.  Add new code, don’t touch the old code  Why should you use it?  Systems easier to change/evolve  Reduces risk  Develop and test extensions in isolation
  • 19. The principles Open/closed Principle Code
  • 20. The principles Liskov Substitution Principle  What is the 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.  Subtypes must be substitutable for their base types.
  • 21. The principles Liskov Substitution Principle  Why should you use it?  Consistent behaviour  Reduces coupling  Makes it easier to evolve code
  • 22. The principles Liskov Substitution Principle Fail
  • 23. The principles Liskov Substitution Principle Code
  • 24. The principles  S ingle Responsibility Principle –> SRP  A class should have only one reason to change.  O pen/Closed Principle –> OCP  Add new code, don’t touch the old code  L iskov Substitution Principle –> LSP  Subtypes must be substitutable for their base types  I nterface Segregation Principle –> ISP  Avoid “fat” interfaces  D ependency Inversion Principle –> DIP  Don’t call us, we’ll call you
  • 25. S.O.L.I.D code is...  Loosely coupled  Highly cohesive  Easy to evolve/change  Testable
  • 26. Summary  Not new, been around a while  Principles not rules  You decide when to apply  It should make it easier to evolve code  Code will be easier to unit test
  • 28. Resources  Principles Of Ood  DimeCasts.Net – screen casts on each principle  Los Techies – series of posts on principles  Hanselminutes – podcast with Uncle Bob  Getting a good SOLID start – post by Uncle bob  Presentation Code – code from the presentation nathangloyn Design Code Release @NathanGloyn nathan@gloyn.co.uk