Improving Software Quality Using
Object Oriented Design Principles
By
Dr. Syed Hassan Amin
Note : Thanks to all those who contributed to creating and improving
these slides.
High Level Overview
• Software Quality
• OOP Design Principles
• OO Best Practices
• Bad Smells of Code
• Details of various principles with examples
• Note : We will not be able to cover everything in this lecture !
Introduction
• In software engineering we normally start with requirement
gathering, analysis, writing features list and design
• At some point you actually are going to write some code.
• And that’s where design principles come into play
Software Quality
• Software quality refers to two related but distinct notions that exist
wherever quality is defined in a business context:-
• Software functional quality reflects how well it complies with or
conforms to a given design, based on functional requirements or
specifications.
• Software structural quality refers to how it meets non-functional
requirements that support the delivery of the functional
requirements, such as robustness or maintainability, the degree to
which the software was produced correctly.
• Properties/Characteristics of software that constitute software
quality are :-
• Flexibility
• Maintainability
• Extendibility
• Reusability
• Testability
What is OO Design Principle?
• A design principle is a basic tool or technique that can be
applied to writing code to make resultant software
maintainable, flexible, extendible and reusable.
• Today we are going to look into some design principles
that people came up with over the years and how they
can make you a better engineer.
• Put aside your thoughts of “doing it your way”; this
presentation is about doing it the smarter and faster way.
OOP Design Principles
• Encapsulation or Information Hiding
• Open-Closed principle(OCP)
• Single responsibility principle(SRP)
• Liskov substitution principle(LSP)
• Don’t repeat yourself(DRY)
• Law of Demeter(LoD)
• Dependency Injection or Inversion of Control(IoC)
OO Best Practices
• Encapsulate what varies
• Code to an interface rather than to an implementation
• Dependency Injection
• Composition better than Inheritance
• Prefer ‘Has a’ over Ís a’
• Use Inheritance Sparingly
• Reduce Coupling, Increase Cohesion
• Classes are about Behavior i.e. No Dumb Data Holders
Bad Smells of Code
• Repeated Code
• Long Method
• Long Class
• Long Parameter List
• Data Class – Dumb Data Holder
• Violation of encapsulation
• Global variable(s)
Open-Close Principle
“Classes should be open for extension, and closed for
modification”
• New functionality should be added with minimum changes in
the existing code.
• The design should be done in a way to allow the adding of
new functionality as new classes, keeping existing code
unchanged.
OCP - Bad Example
OCP – Bad Example
OCP – Good Example
OCP – Good Example
Like every principle OCP is only a principle. Making a flexible design involves
additional time and effort ,and it introduce new level of abstraction increasing the
complexity of the code.
So this principle should be applied in those areas which are most likely to be
changed.
Single Responsibility
Principle(SRP)
“A class should have only one reason to change”
• This principle states that if we have 2 reasons to change for a
class, we have to split the functionality in two classes.
• Each class will handle only one responsibility and in the future
if we need to make one change we are going to make it in the
class which handle it.
• When we need to make a change in a class having more
responsibilities the change might effect the other functionality
of the classes.
Single Responsibility Principle
Is this qualify Single Responsibility Principle (SRP) ?
SRP Spottingmultipleresponsibilities
Liskov Substitution
Principle(LSP)
“Sub Type must be substitutable for their base type”
• We must make sure that the new derived classes just extend
without replacing the functionality of base classes.
• Liskov’s substitution principle states that if a program module
is using a base class, then the reference to the base class can
be replaced with a derived class without affecting the
functionality of the program module.
LSP – Bad Example
• Extend Board to produce 3D
board
• Analyze the design to find out
design problems
• This Principle is just an extension
of Open-Close Principle
• The focus of this principle is to
make sure that new derived
classes are extending the base
class without changing their
behavior
LSP – Bad Example
• But this means that an instance of Board3D looks like this:
• Each attribute and method in bold is meaningless in this object
• Board3D is getting nothing useful from Board except for width
and height
• We certainly could NOT create a Board3D object and hand it to
code expecting a Board object!
• As a result, this design violates the
LSP principle
LSP – Delegation comes to
rescue
• Board3D example violated LSP because of inappropriate use of
inheritance.
• Thus, if you need to use functionality in another class, but you
don’t want to change that functionality, consider using
delegation instead of inheritance
• Inheritance was simply the wrong way to gain access to the
Board’s functionality
• Delegation is when you hand over the responsibility for a
particular task to some other class or method
LSP – Delegation comes to
rescue (Cont’d)
• Board3D now maintains a
list of Board objects for
each legal value of “zpos”
• It then delegates to the
Board object to handle
the requested service
public Tile getTile(int x, int
y, int z) {
Board b = boards.get(z);
return b.getTile(x,y);
}
Don’t Repeat Yourself (DRY)
“Avoid duplicate code by abstracting out things that are
common and putting these in a single location”
DRY is about having each piece of information and behavior in
your system in a single sensible place.
DRY – Bad Example
DRY – Correcting Bad Example
1- Let’s abstract out the common code
DRY – Correcting Bad Example
2- Now remove the code from other locations
That’s it! 
Encapsulate What Varies
• Anytime you have behavior in an application that you think is likely
to change, you want to move that behavior away from parts of
your application that probably won’t change very frequently.
• In other words you should always try to encapsulate what varies.
EWV- Example
It helps protect your classes from unnecessary changes.
Code To An Interface Principle
“Code to an interface rather than to an implementation”
• Coding to an interface, rather than to an implementation
makes your software easier to extend and reuse
• Objective is to hide implementation details thus reducing
coupling and increasing cohesion
• Any time you are writing code that interact with other classes,
you have two choices.
• You can write code that interact directly with sub class, Like
BaseballPlayer, or you can write code that interact with Athlete.
• When you run into the choice like this, you should always favor
coding to the interface, not to the implementation.
Code To Interface… Example
Use Inheritance Sparingly
• Rule of thumb : (almost)
• Inherit only when clear ‘is a’ relation exists AND
• All the members in base Class will be used/implemented in sub
classes
• If you use inheritance other than these rules, highly probably
you are mistaken
Inappropriate use
• Board3D is not a Board2D
• Board3D will have useless members eventually,
like tiles : int[][]
• All the methods of Board2D will become useless
in Board3D
• Inheritance is surely not the option
Solution
• Board3D is composed of Board2D
• We have “depth” times Board2Ds in our Board3D class
• All the operations are delegated to Board2D methods
• Board3D methods will use respective Board2D methods for “depth” times
• Composition and delegation is better choice
Summary
We have covered some basic object oriented design principles
that help us to write the code which is more maintainable and
extensible.
Following are some more principles which you can see by
yourself
• Dependency Injection Principle
• Favor Composition Over Inheritance
References
• http://www.oodesign.com/design-principles.html
• http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
• Head First Object Oriented Analysis and Design (O’Reilly)

Improving Software Quality Using Object Oriented Design Principles

  • 1.
    Improving Software QualityUsing Object Oriented Design Principles By Dr. Syed Hassan Amin Note : Thanks to all those who contributed to creating and improving these slides.
  • 2.
    High Level Overview •Software Quality • OOP Design Principles • OO Best Practices • Bad Smells of Code • Details of various principles with examples • Note : We will not be able to cover everything in this lecture !
  • 3.
    Introduction • In softwareengineering we normally start with requirement gathering, analysis, writing features list and design • At some point you actually are going to write some code. • And that’s where design principles come into play
  • 4.
    Software Quality • Softwarequality refers to two related but distinct notions that exist wherever quality is defined in a business context:- • Software functional quality reflects how well it complies with or conforms to a given design, based on functional requirements or specifications. • Software structural quality refers to how it meets non-functional requirements that support the delivery of the functional requirements, such as robustness or maintainability, the degree to which the software was produced correctly. • Properties/Characteristics of software that constitute software quality are :- • Flexibility • Maintainability • Extendibility • Reusability • Testability
  • 5.
    What is OODesign Principle? • A design principle is a basic tool or technique that can be applied to writing code to make resultant software maintainable, flexible, extendible and reusable. • Today we are going to look into some design principles that people came up with over the years and how they can make you a better engineer. • Put aside your thoughts of “doing it your way”; this presentation is about doing it the smarter and faster way.
  • 6.
    OOP Design Principles •Encapsulation or Information Hiding • Open-Closed principle(OCP) • Single responsibility principle(SRP) • Liskov substitution principle(LSP) • Don’t repeat yourself(DRY) • Law of Demeter(LoD) • Dependency Injection or Inversion of Control(IoC)
  • 7.
    OO Best Practices •Encapsulate what varies • Code to an interface rather than to an implementation • Dependency Injection • Composition better than Inheritance • Prefer ‘Has a’ over Ís a’ • Use Inheritance Sparingly • Reduce Coupling, Increase Cohesion • Classes are about Behavior i.e. No Dumb Data Holders
  • 8.
    Bad Smells ofCode • Repeated Code • Long Method • Long Class • Long Parameter List • Data Class – Dumb Data Holder • Violation of encapsulation • Global variable(s)
  • 9.
    Open-Close Principle “Classes shouldbe open for extension, and closed for modification” • New functionality should be added with minimum changes in the existing code. • The design should be done in a way to allow the adding of new functionality as new classes, keeping existing code unchanged.
  • 10.
    OCP - BadExample
  • 11.
    OCP – BadExample
  • 12.
    OCP – GoodExample
  • 13.
    OCP – GoodExample Like every principle OCP is only a principle. Making a flexible design involves additional time and effort ,and it introduce new level of abstraction increasing the complexity of the code. So this principle should be applied in those areas which are most likely to be changed.
  • 14.
    Single Responsibility Principle(SRP) “A classshould have only one reason to change” • This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes. • Each class will handle only one responsibility and in the future if we need to make one change we are going to make it in the class which handle it. • When we need to make a change in a class having more responsibilities the change might effect the other functionality of the classes.
  • 15.
    Single Responsibility Principle Isthis qualify Single Responsibility Principle (SRP) ?
  • 16.
  • 17.
    Liskov Substitution Principle(LSP) “Sub Typemust be substitutable for their base type” • We must make sure that the new derived classes just extend without replacing the functionality of base classes. • Liskov’s substitution principle states that if a program module is using a base class, then the reference to the base class can be replaced with a derived class without affecting the functionality of the program module.
  • 18.
    LSP – BadExample • Extend Board to produce 3D board • Analyze the design to find out design problems • This Principle is just an extension of Open-Close Principle • The focus of this principle is to make sure that new derived classes are extending the base class without changing their behavior
  • 19.
    LSP – BadExample • But this means that an instance of Board3D looks like this: • Each attribute and method in bold is meaningless in this object • Board3D is getting nothing useful from Board except for width and height • We certainly could NOT create a Board3D object and hand it to code expecting a Board object! • As a result, this design violates the LSP principle
  • 20.
    LSP – Delegationcomes to rescue • Board3D example violated LSP because of inappropriate use of inheritance. • Thus, if you need to use functionality in another class, but you don’t want to change that functionality, consider using delegation instead of inheritance • Inheritance was simply the wrong way to gain access to the Board’s functionality • Delegation is when you hand over the responsibility for a particular task to some other class or method
  • 21.
    LSP – Delegationcomes to rescue (Cont’d) • Board3D now maintains a list of Board objects for each legal value of “zpos” • It then delegates to the Board object to handle the requested service public Tile getTile(int x, int y, int z) { Board b = boards.get(z); return b.getTile(x,y); }
  • 22.
    Don’t Repeat Yourself(DRY) “Avoid duplicate code by abstracting out things that are common and putting these in a single location” DRY is about having each piece of information and behavior in your system in a single sensible place.
  • 23.
    DRY – BadExample
  • 24.
    DRY – CorrectingBad Example 1- Let’s abstract out the common code
  • 25.
    DRY – CorrectingBad Example 2- Now remove the code from other locations That’s it! 
  • 26.
    Encapsulate What Varies •Anytime you have behavior in an application that you think is likely to change, you want to move that behavior away from parts of your application that probably won’t change very frequently. • In other words you should always try to encapsulate what varies.
  • 27.
    EWV- Example It helpsprotect your classes from unnecessary changes.
  • 28.
    Code To AnInterface Principle “Code to an interface rather than to an implementation” • Coding to an interface, rather than to an implementation makes your software easier to extend and reuse • Objective is to hide implementation details thus reducing coupling and increasing cohesion • Any time you are writing code that interact with other classes, you have two choices. • You can write code that interact directly with sub class, Like BaseballPlayer, or you can write code that interact with Athlete. • When you run into the choice like this, you should always favor coding to the interface, not to the implementation.
  • 29.
  • 30.
    Use Inheritance Sparingly •Rule of thumb : (almost) • Inherit only when clear ‘is a’ relation exists AND • All the members in base Class will be used/implemented in sub classes • If you use inheritance other than these rules, highly probably you are mistaken
  • 31.
    Inappropriate use • Board3Dis not a Board2D • Board3D will have useless members eventually, like tiles : int[][] • All the methods of Board2D will become useless in Board3D • Inheritance is surely not the option
  • 32.
    Solution • Board3D iscomposed of Board2D • We have “depth” times Board2Ds in our Board3D class • All the operations are delegated to Board2D methods • Board3D methods will use respective Board2D methods for “depth” times • Composition and delegation is better choice
  • 33.
    Summary We have coveredsome basic object oriented design principles that help us to write the code which is more maintainable and extensible. Following are some more principles which you can see by yourself • Dependency Injection Principle • Favor Composition Over Inheritance
  • 34.