Lecture 07
Design Principles
Agenda
 Why Principles?
 SOLID Principle
1. Single Responsibility Principle
2. Open/Closed Principle
3. Liskov Substitution Principle
4. Interface Segregation Principle
5. Dependency Inversion Principle
Reading
 Barbin Chapter 5 SOLID Principles
Big Ball of Mud
 Is this your code?
Why Principles?
 Based on knowledge and research
 Encourage writing high quality code
 Promote better communication
Why Principles?
 Should not be taken as dogmatic
 All design decision have context and specific set
of problems to solve
SOLID Principles
 Object oriented design and development
1. Single Responsibility Principle
2. Open/Closed Principle
3. Liskov Substitution Principle
4. Interface Segregation Principle
5. Dependency Inversion Principle
Single Responsibility Principle
(SRP)
 Class should have one and only one reason to
change
 Violating this principle leads to low cohesion
and make the code brittle and loads to code
bloat and confusion
Single Responsibility Principle
 Cohesion refers to the degree to which the
elements of a module belong together
– if the methods that serve the given class tend to be
similar in many aspects, then the class is said to have
high cohesion
 High cohesion
– Increased understanding of modules
– Increased ease in maintaining a system
– Increased ease in reusing a module
Single Responsibility Principle
 Example:
– Rectangle has two responsibities
The Open-Closed Principle (OCP)
 Design and write code in a fashion that adding
new functionality would involve minimal changes
to existing code
– Most changes will be handled as new methods and
new classes
– Designs following this principle would result in
resilient code which does not break on addition of
new functionality
public class ResourceAllocator
{
...
public int allocate(intresourceType)
{
intresourceId;
switch (resourceType)
{
case TIME_SLOT:
resourceId = findFreeTimeSlot();
markTimeslotBusy(resourceId);
break;
case SPACE_SLOT:
resourceId = findFreeSpaceSlot();
markSpaceSlotBusy(resourceId);
break;
...
}
return resourceId;
}
...
Resource Allocator Example
Holy Buckets!!
I need to change
the class for new
types!!! Horrible!
Resource Allocator Example
 Design for extensions
List resources = new ArrayList();
...
public int allocate(intresourceType)
{
int resourceId = findFreeResource(resourceType);
markAsBusy(resourceId);
return resourceId;
}
The Liskov Substitution Principle
(LSP)
 All code operating with reference to the base
class should be completely transparent to the
type of the inherited object
 It should be possible to substitute an object of
one type with another within the same class
hierarchy
 Inheriting classes should not perform any
actions that will invalidate the assumptions
made by the base class
LSP Example
public class Rectangle {
protected int _width;
protected int _height;
public int getWidth() {
return _width;
}
public int getHeight() {
return _height;
}
public void setWidth(int width) {
_width = width;
}
public void setHeight(int height) {
_height = height;
}
}
LSP Example
public class Square extends Rectangle {
public void setWidth(int width) {
_width = width;
_height = width;
}
public void setHeight(int height) {
_height = height;
_width = _height;
}
}
Implementation convenience
LSP Example
import junit.framework.Assert;
import org.junit.Test;
public class RectangleTests {
@Test
public void areaOfRectangle() {
Rectangle r = new Square();
r.setWidth(5);
r.setHeight(2);
// Will Fail - r is a square and sets
// width and height equal to each other.
Assert.assertEquals(r.getWidth() * r.getHeight(),10);
}
}
Interface Segregation Principle
(ISP)
 Split large interfaces into smaller and more
specific interfaces
– Role interfaces
– The smaller the interface, the better
 Large interfaces
– Fat or polluted interfaces
– Clients are forced to depend on methods they do not
use
Dependency Inversion Principle
(DIP)
 Low-level components should depend on high-
level, not vice versa. This is dependency
Inversion
 The high-level components should be the one
defining logic and enforcing change
 High-level components depending on low-level
components decreases the capability of the
high-level components
Dependency Inversion Principle
 Separated interface pattern
 Program to interfaces
 Dependency inversion is the very heart of
framework design
Dependency Inversion Principle
 Dependency inversion means
– High-level components should not depend on low-
level components, both should depend on
abstractions
– Abstractions should not depend on details, details
should depend on abractions
Summary
 Framework patterns
– Inversion of Control and Dependency Injection
– Template Method
– Strategy
 From problems to patterns
– Game Framework
 Spring framework
– Bean containers
– BeanFactory and ApplicationContext

L07 Design Principles

  • 1.
  • 2.
    Agenda  Why Principles? SOLID Principle 1. Single Responsibility Principle 2. Open/Closed Principle 3. Liskov Substitution Principle 4. Interface Segregation Principle 5. Dependency Inversion Principle
  • 3.
    Reading  Barbin Chapter5 SOLID Principles
  • 4.
    Big Ball ofMud  Is this your code?
  • 5.
    Why Principles?  Basedon knowledge and research  Encourage writing high quality code  Promote better communication
  • 6.
    Why Principles?  Shouldnot be taken as dogmatic  All design decision have context and specific set of problems to solve
  • 7.
    SOLID Principles  Objectoriented design and development 1. Single Responsibility Principle 2. Open/Closed Principle 3. Liskov Substitution Principle 4. Interface Segregation Principle 5. Dependency Inversion Principle
  • 8.
    Single Responsibility Principle (SRP) Class should have one and only one reason to change  Violating this principle leads to low cohesion and make the code brittle and loads to code bloat and confusion
  • 9.
    Single Responsibility Principle Cohesion refers to the degree to which the elements of a module belong together – if the methods that serve the given class tend to be similar in many aspects, then the class is said to have high cohesion  High cohesion – Increased understanding of modules – Increased ease in maintaining a system – Increased ease in reusing a module
  • 10.
    Single Responsibility Principle Example: – Rectangle has two responsibities
  • 11.
    The Open-Closed Principle(OCP)  Design and write code in a fashion that adding new functionality would involve minimal changes to existing code – Most changes will be handled as new methods and new classes – Designs following this principle would result in resilient code which does not break on addition of new functionality
  • 12.
    public class ResourceAllocator { ... publicint allocate(intresourceType) { intresourceId; switch (resourceType) { case TIME_SLOT: resourceId = findFreeTimeSlot(); markTimeslotBusy(resourceId); break; case SPACE_SLOT: resourceId = findFreeSpaceSlot(); markSpaceSlotBusy(resourceId); break; ... } return resourceId; } ... Resource Allocator Example Holy Buckets!! I need to change the class for new types!!! Horrible!
  • 13.
    Resource Allocator Example Design for extensions List resources = new ArrayList(); ... public int allocate(intresourceType) { int resourceId = findFreeResource(resourceType); markAsBusy(resourceId); return resourceId; }
  • 14.
    The Liskov SubstitutionPrinciple (LSP)  All code operating with reference to the base class should be completely transparent to the type of the inherited object  It should be possible to substitute an object of one type with another within the same class hierarchy  Inheriting classes should not perform any actions that will invalidate the assumptions made by the base class
  • 15.
    LSP Example public classRectangle { protected int _width; protected int _height; public int getWidth() { return _width; } public int getHeight() { return _height; } public void setWidth(int width) { _width = width; } public void setHeight(int height) { _height = height; } }
  • 16.
    LSP Example public classSquare extends Rectangle { public void setWidth(int width) { _width = width; _height = width; } public void setHeight(int height) { _height = height; _width = _height; } } Implementation convenience
  • 17.
    LSP Example import junit.framework.Assert; importorg.junit.Test; public class RectangleTests { @Test public void areaOfRectangle() { Rectangle r = new Square(); r.setWidth(5); r.setHeight(2); // Will Fail - r is a square and sets // width and height equal to each other. Assert.assertEquals(r.getWidth() * r.getHeight(),10); } }
  • 18.
    Interface Segregation Principle (ISP) Split large interfaces into smaller and more specific interfaces – Role interfaces – The smaller the interface, the better  Large interfaces – Fat or polluted interfaces – Clients are forced to depend on methods they do not use
  • 20.
    Dependency Inversion Principle (DIP) Low-level components should depend on high- level, not vice versa. This is dependency Inversion  The high-level components should be the one defining logic and enforcing change  High-level components depending on low-level components decreases the capability of the high-level components
  • 21.
    Dependency Inversion Principle Separated interface pattern  Program to interfaces  Dependency inversion is the very heart of framework design
  • 23.
    Dependency Inversion Principle Dependency inversion means – High-level components should not depend on low- level components, both should depend on abstractions – Abstractions should not depend on details, details should depend on abractions
  • 24.
    Summary  Framework patterns –Inversion of Control and Dependency Injection – Template Method – Strategy  From problems to patterns – Game Framework  Spring framework – Bean containers – BeanFactory and ApplicationContext

Editor's Notes