Software Design Principles - PowerPoint PPT Presentation

About This Presentation
Title:

Software Design Principles

Description:

Class Rectangle may be forced to make changes from two different unrelated sources. ... A client should not be forced to depend on methods it does not use. ... – PowerPoint PPT presentation

Number of Views:91
Avg rating:3.0/5.0
Slides: 24
Provided by: YB
Category:

less

Transcript and Presenter's Notes

Title: Software Design Principles


1
Software Design Principles
  • August 19, 2005

2
Software design principles
  • The single-responsibility principle
  • The open-closed principle
  • The Liskov substitution principle
  • The dependency inversion principle
  • The interface segregation principle

3
The single-responsibility principle
  • A class should have only one reason to change.
    -- Robert Martin
  • A responsibility a reason to change
  • Separate coupled responsibilities into separate
    classes

4
The single-responsibility principle
  • Example
  • Often we need to sort students by their name, or
    ssn. So one may make Class Student implement the
    Java Comparable interface.
  • class Student implements Comparable
  • int compareTo(Object o)
  • Student is a business entity, it does not know in
    what order it should be sorted since the order of
    sorting is imposed by the client of Student.
  • Worse every time students need to be ordered
    differently, we have to recompile Student and all
    its client.
  • Cause of the problems we bundled two separate
    responsibilities (i.e., student as a business
    entity with ordering) into one class a
    violation of SRP

5
The single-responsibility principle
Register Add(Course d, Student s)
When a new requirement needs to sort students in
a different order, Student, Register, and AClient
all need to be recompiled, even Register has
nothing to do with any ordering of Students.
It invokes Collections.sort(aListofStudents)
6
The single-responsibility principle
The solution is to separate the two
responsibilities into two separate classes and
use another version of Collections.sort().
It invokes Collections.sort(aListofStudents,
StudentBySSN)
7
The single-responsibility principle
Computational Geometry Application
Graphical Application
GUI
Class Rectangle may be forced to make changes
from two different unrelated sources. One is from
the Computational Geometry Application (CGA).
E.g., adding area function for length and width
of type double. The other is from Graphical
Application (GA). E.g., add draw() in Windows XP
to the existing draw in X Windows. A change from
either of the two source would still cause the
other application to recompile.
8
The single-responsibility principle
Computational Geometry Application
Graphical Application
Graphic Rectangle draw()void
Geometric Rectangle area()double
GUI
  • Package CGA is no longer dependent on graphical
    side of Rectangle and thus it becomes independent
    of package GUI. Any change caused by graphical
    application no longer requires CGA to be
    recompiled.
  • However, any changes from the CGA side may cause
    GA to be recompiled.

9
The single-responsibility principle
Computational Geometry Application
Graphical Application
Rectangle -double length -double
width getLength()dobule getWidth()dobule
Graphic Rectangle draw()void
Geometric Rectangle area()double
GUI
Class Rectangle contains the most primitive
attributes and operations of rectangles. Classes
GeometricRectangle and GraphicRectangle are
independent of each other. A change from either
side of CGA or GA, it would not cause the other
side to be recompiled. NOTE this does not
violate LSP, since Rectangle does not have any
client.
10
The open-closed principle
  • Software entities (classes, modules, functions,
    etc,) should be open for extension, but closed
    for modification. R. Martin
  • To make a class open for extension, closed for
    modification, program the class to interfaces (or
    abstract classes), not implementation (concrete
    classes).

11
The open-closed principle
Employee int EmpType
Faculty getOffice()
Staff getDept()
Secretary getTypeSpeed()
Engineer getEngTYpe()
void printEmpRoster(Employee emps) for
(int i iltemps.size() i) if
(empsi.empType FACULTY)
printfFaculty((Faculty)empsi) else
if (empsi.empType STAFF)
printStaff((Staff)empsi) else if
(empsi.empType SECRETARY)
printSecretary((Secretary)empsi)
What if we need to add Engineer??
12
The open-closed principle
Employee printInfo()
Faculty printInfo()
Staff printInfo()
Secretary printInfo
Engineer printInfo()
void printEmpRoster(Employee emps) for
(int i iltemps.size() i)
empsi.printInfo()
When Engineer is added, printEmpRoster() does not
even need to recompile. PrintEmpRoster() is open
to extension, closed for modification.
13
The open-closed principle
  • Three versions of SORT
  • sort(List list)
  • Elements of list must implement Comparable
    interface
  • sort(List list, StringComparator sc)
  • Elements of list are not required to implement
    Comparable
  • StringComparator orders objects of String only
  • Sort(List list, Comparator comp)
  • Elements of list are not required to implement
    Comparable
  • Comparator may compare objects of any type.
  • Open to extension since it can sort objects of
    any type at any order specified in the second
    parameter.

14
The Liskov substitution principle
  • Subtypes must be substitutable for their base
    types. R. Martin
  • Demand no more, promise no less
  • Demand no more the subclass would accept any
    arguments that the superclass would accept.
  • Promise no less Any assumption that is valid
    when the superclass is used must be valid when
    the subclass is used.
  • Interface inheritance The LSP should be
    conformed to.
  • Implementation inheritance use composition
    instead of inheritance (in Java) or use private
    base classes (in C).

15
The Liskov substitution principle
  • Implementation inheritance
  • When you use List to implement Queue (in Java),
    use composition, not inheritance.
  • The intention is that you use only Lists
    implementation

ltfoundationgt List insert() delete() find()
List insert() delete() find()
List insert() delete() find()
MyList
Queue enqueue() dequeue() isEmpty()
Queue enqueue() dequeue() isEmpty()
Queue enqueue() dequeue() isEmpty()
16
The Liskov substitution principle
class Square extends Rectangle public void
setWidth(int width) super.setWidth(width)
super.setHeight(width) public
void setHeight(int height)
super.setHeight(height)
super.setWidth(height) void
clientOfRectangle(Rectangle r)
r.setWidth(10) r.setHeight(20)
print(r.area()) Rectangle r new
Square() clientOfRectangle(r) // what would be
printed?
Rectangle -int width -int height getWidth() set
Width() getHeight() setHeight() area()
IS-A
Square getWidth() setWidth() getHeight() setHe
ight()
17
The Liskov substitution principle
  • Rectangle and Square
  • Invariant of Rectangle width and height are
    independent of each other (which can be expected
    from the setWidth and setHeight operations)
  • Square violates the width-height-independence
    invariant of Rectangle

18
The Liskov substitution principle
  • There are cases in which the substitutability may
    not be needed
  • Specialization we found that Faculty, Staff,
    Secretary and Engineer all have the same set of
    attributes and operations, so we created the
    Employee as a placeholder for those common
    properties.
  • For the system, there is no client for Employee
  • Thus, the four subclasses do not need to be
    substitutable
  • Actually, there is no way we can tell whether
    they are or not.

Employee printInfo()
Faculty printInfo()
Staff printInfo()
Secretary printInfo
Engineer printInfo()
Specialization
19
The dependency inversion principle
  • Abstraction should not depend on details.
    Details should depend on abstraction. R.
    Martin
  • High-level concepts are more stable than
    low-level implementation

20
The dependency inversion principle
Policy Layer
High-level modules make calls to low-level
modules.
Mechanism Layer
Utility Layer
The upper-level layer is dependent upon
lower-level layers.
21
The dependency inversion principle
Dependency Inversion Lower-level layers is
dependent upon upper-level layers.
Policy
Policy Layer
Mechanism
Mechanism Layer
ltltinterfacegtgt Policy Service
Utility
ltltinterfacegtgt Mechanism Service
Utility Layer
Ownership Inversion The client (upper-level
layer) owns the interface, not the lower-level
layers
22
The interface segregation principle
  • Clients should not be forced to depend on
    methods that they do not use. R. Martin
  • When we bundle functions for different clients
    into one interface/class, we create unnecessary
    coupling among the clients.
  • When one client causes the interface to change,
    all other clients are forced to recompile.

23
Software design principles - summary
  • The single-responsibility principle
  • There is only one source that may the class to
    change
  • The open-closed principle
  • Open to extension, closed for modification
  • The Liskov substitution principle
  • A subclass must substitutable for its base class
  • The dependency inversion principle
  • Low-level (implementation, utility) classes
    should be dependent on high-level (conceptual,
    policy) classes
  • The interface segregation principle
  • A client should not be forced to depend on
    methods it does not use.
Write a Comment
User Comments (0)
About PowerShow.com