Influencing policy (training slides from Fast Track Impact)
Design Patterns and Principles Explained
1. DESIGN PATTERNS
S.SRIKRISHNAN
FINAL YEAR
DEPARTMENT OF COMPUTER SCIENCE
SSN COLLEGE OF ENGINEERING
2. Overview
• Introduction
• Software Architecture
• Issues in Software Development
• GoF patterns
• Basic Class relationships
• Design Principles – 1,2,3
• Design Principles to Design Patterns
• Observer Pattern
3. Introduction
• “Programming is fun, but developing quality
software is hard” – Craig Larman
• The focus is on OO software development
• Built using OO Framework – Java, .NET,
Python, C++, Smalltalk etc.
• “Owning a hammer doesn’t make one an
architect”
• Many issues during development have to be
resolved
7. Issues in Software Development
• Unclear requirements
• Continuously changing requirements
• Miscommunications
• How to design the software classes – Huh ! Looks
like the most difficult problem
• How to assign responsibilities to classes – What
classes should do what?
• All these imply something - The code being
developed should be reusable, highly cohesive
and less coupled
8. Design Patterns come to our rescue
• They are elements of reusable Object Oriented
Software
• Try to exploit the wisdom and lessons learnt by the
OO developers who faced similar design problems
• An object-oriented system's quality can be judged
looking at the manner in which patterns have been
used
• Several design patterns have been suggested by the
GoF (Gang of Four)
9. GoF – Who are they ?
• Erich Gamma, Richard
Helm, Ralph Johnson, John
Vlissides (Gang of Four)
• They published a book
“Design Pattens by GoF” in
1994 which was a major
milestone in OO
development
• This book is considered the
“bible” for Design Patterns
• It describes 23 patterns for
good OO design
11. Basic Class Relationships
• Generalization (Is – a)
• Realization (Implements – a)
• Association (Has – a / uses)
• Composition (Is composed of)
12. Design Principles
• “Identify the aspects of your application that
vary and separate them from what stays the
same”
• “Program to an interface, not an
implementation”
• “Favor composition over inheritance”
13. Design Principle – 1
• “Identify the aspects of your application that
vary and separate them from what stays the
same”
• Take the parts that vary and encapsulate them
• You can later alter or extend the parts that vary
without affecting those that don’t
• Let’s see how to apply this for a Duck class
14. Designing a Duck class
• A duck may fly, quack – depends on the type of duck
(sub classes of Duck)
• So, can we put quack and fly methods in Duck class?
– A problem, because all types may not quack or fly
• So, can we have these methods in duck class, and
override them in sub classes, so that ducks that should
not fly or quack will override to do nothing?
– A bigger problem, because, it is unstable to
changes
15. Designing a Duck class
• So, what about an interface?
• Lets define an interface Flyable with fly
method and Quackable with Quack method
• All sub ducks extend Duck class and
implement the necessary interface(s)
• Does that solve this problem really?
– No, it shows no improvement
– Code is still not reusable
16. Designing a Duck class
• So here lies the problem : Quack and fly
methods have to be implemented in all the sub
classes.
• If there is a need to change the flying or
quacking style, we need to go to all classes and
modify them
• Let’s try to find a solution to this : Apply the
previously mentioned principle
17. Applying the design principle
• Pull out what varies : Quack and Fly behaviour
• Allocate separate interfaces FlyBehaviour and
QuackBehaviour
• Write 2 classes FlyWithWings and FlyNoWay
that implements FlyBehaviour
• Write 2 more classes Quack and MuteQuack
that implements QuackBehaviour
18. Applying the design principle
• Override fly method in FlyWithWings with
necessary implementation and in FlyNoWay
without any implementation
• Override quack method in Quack with
necessary implementation and in NoQuack
without any implementation
• Create an association with the Duck class and
the two encapsulated Behaviour classes :
FlyBehaviour and QuackBehaviour
19. Design Principle – 2
• “Program to an interface, not an
implementation”
• Programming to an interface means
programming to a super type
• This helps in exploiting polymorphism : the
actual runtime object isn’t locked into the code
• Objects assigned can be any concrete
implementation of the super type
20. Design Principle – 3
• “Favor composition over inheritance”
• It adds flexibility to the code
• It helps encapsulate family of algorithms
• It helps us change behavior at runtime
• As seen in the above example, composition
yields better design than inheritance
21. From principles to patterns
• All patterns that have been framed adopt the 3
basic design principles
• When you use a pattern in a description, other
developers quickly know precisely the design
you have in your mind
• A team well versed in design patterns can
move forward more quickly with less room for
misunderstanding
22. Observer Pattern
• Most widely used patterns in the JDK
• Publisher – Subscriber Pattern
• Event Delegation Model
• Different kinds of subscriber objects are
interested in the state change or events of a
publisher object, and want to react in their own
unique way when the publisher generates an
event.
23. Observer Pattern
• Define a subscriber or listener interface
• Subscribers implement this interface
• The publisher can dynamically register
subscribers who are interested in an event and
notify them when an even occurs.
• We could implement the Observer pattern
“from scratch” in Java
• Java provides the Observable/Observer classes
as built-in support for the Observer pattern
24. Observer Pattern
• The java.util.Observable class is the base Subject
class. Any Class that wants to be observed
extends this class
– Provides methods to add/delete observers
– Provides methods to notify all observers
– A subclass only needs to ensure that its observers are
notified in the appropriate mutators
– Uses a Vector for storing the observer references
• The java.util.Observer interface is the Observer
interface. It must be implemented by any
observer class
25. Observer Pattern
/**
* A subject to observe!
*/
public class ConcreteSubject extends Observable {
private String name;
private float price;
public ConcreteSubject(String name, float price) {
this.name = name;
this.price = price;
System.out.println("ConcreteSubject created: " + name + "
at "
+ price);
}
26. Observer Pattern
public String getName() {return name;}
public float getPrice() {return price;}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}
public void setPrice(float price) {
this.price = price;
setChanged();
notifyObservers(new Float(price));
}
}
27. Observer Pattern
// An observer of name changes.
public class NameObserver implements Observer {
private String name;
public NameObserver() {
name = null;
System.out.println("NameObserver created: Name is " + name);
}
public void update(Observable obj, Object arg) {
if (arg instanceof String) {
name = (String)arg;
System.out.println("NameObserver: Name changed to " + name);
} else {
System.out.println("NameObserver: Some other change to
subject!");
}
}
28. Observer Pattern
// An observer of price changes.
public class PriceObserver implements Observer {
private float price;
public PriceObserver() {
price = 0;
System.out.println("PriceObserver created: Price is " + price);
}
public void update(Observable obj, Object arg) {
if (arg instanceof Float) {
price = ((Float)arg).floatValue();
System.out.println("PriceObserver: Price changed to " +
price);
} else {
System.out.println(”PriceObserver: Some other change to
subject!");
}}
29. Observer Pattern
// Test program for ConcreteSubject, NameObserver and PriceObserver
public class TestObservers {
public static void main(String args[]) {
// Create the Subject and Observers.
ConcreteSubject s = new ConcreteSubject("Corn Pops", 1.29f);
NameObserver nameObs = new NameObserver();
PriceObserver priceObs = new PriceObserver();
// Add those Observers!
s.addObserver(nameObs);
s.addObserver(priceObs);
// Make changes to the Subject.
s.setName("Frosted Flakes");
s.setPrice(4.57f);
s.setPrice(9.22f);
s.setName("Sugar Crispies");
}
}
30. Observer Pattern
• Test program output
ConcreteSubject created: Corn Pops at 1.29
NameObserver created: Name is null
PriceObserver created: Price is 0.0
PriceObserver: Some other change to subject!
NameObserver: Name changed to Frosted Flakes
PriceObserver: Price changed to 4.57
NameObserver: Some other change to subject!
PriceObserver: Price changed to 9.22
NameObserver: Some other change to subject!
PriceObserver: Some other change to subject!
NameObserver: Name changed to Sugar Crispies
31. Many more Pattern
• Decorator Pattern
• Factory Pattern
• Singleton Pattern
• Command Pattern
• Template Method Pattern
• Adapter Pattern
• State Pattern
• Proxy Pattern etc.