Design Patterns
In Application development:
The Only Constant is Change
OOP Design Principles
● Explain them via the “SimuDuck” app
○ An application for showing ducks that can swim & make
sounds
Types of Ducks
OOP Design Principles
● Explain them via the “SimuDuck” app
○ An application for showing ducks that can swim & make
sounds
All Ducks can Swim and
make sounds Display is abstract,
Superclass take care of Ducks look different
the implementation
Each subclass has its own
implementation of Display
Requirement Changes
● A new requirement came in to add fly feature
Requirement Changes
● A new requirement came in to add fly feature
Requirement Changes
● This time a new requirement came in to add a new types of
ducks
○ Rubber ducks
Requirement Changes
● This time a new requirement came in to add a
new types of ducks
○ Rubber ducks
● Solution:
○ Create a new class “RubberDuckClass” which
inherits the Duck superclass
■ Override the quack() method as this type
does not make sense (This kind of Duck
doesn’t quack)
● A great use of inheritance for the purpose of
code reusability
What is wrong with this design?
Analysis of the Design
● Inappropriate behavior for a subclass
○ The Rubber ducks are not supposed to fly
○ Adding the fly() method in the superclass gave the flying feature to all subclasses
Because of inheritance a subclass was given an inappropriate feature
What is Wrong?
● Inappropriate behaviour for a subclass
○ The Rubber ducks are not supposed to fly
○ Adding the fly() method in the superclass gave
the flying feature to all subclasses
● Solution:
Fix to the issue/ inheriting an inappropriate
feature
● Solution:
○ Override the fly() method in the same
way as the quack() was overridden
What is Wrong?
● The issue now is that fly() and
quack() methods needs to be
implemented in each subclass
Every Subclass needs to override the fly feature
Why this is not a good solution
● The design is inflexible
● Inheritance did not solve the problem of changing requirement
● The duck behaviour keeps changing
○ Not all features (properties) are needed by all subclasses
○ The changing features need to be overridden appropriately
in each subclass
Using Interfaces
● Take changing behaviour out of the
superclass
● Have an interface for each
behaviour that is changing
○ An interface for the flying behaviour
○ Another one for the sound behaviour
● Each subclass will implement the
ones that it needs
Does the interface solve the problem?
● Interfaces do not have implementation
○ Each subclass has its own implementation
● Changing the behaviour
○ For example, if we want to change the fly()
■ then we need to visit all subclasses and do the
changes
○ This destroys the code reuse, makes code maintenance
hard, and might introduce bugs
In Application development:
The Only Constant is Change
The Application must grow and change or it will die
First Design Principle
Identify the aspects of application that vary and separate
them from what stays the same
take the parts that vary and encapsulate them, so that
later you can alter or extend the parts that vary without
affecting those that don’t.
Encapsulate What Varies
● Take out what have a changing
behaviour and encapsulate them
○ modifying/extending them becomes
possible without affecting parts that do
not change
● In the SimUDuck
○ Take out the fly and quack
■ Make a class to represent each behaviour;
flying & quacking
■ Each behaviour will contain various
implementation
■ Include setter methods for these behaviours
in the Duck class
What did we achieve?
● We have new classes with the only purpose is to represent a
changing behaviour
○ Instead of relying
■ On concrete implementation in the superclass (Duck class)
■ Or on specialized implementation in the subclass
● These behaviours can be reused, and a new type of behaviours
can be easily added
Second design principle: Program to an interface, not an
implementation
“Program to an interface ” really means “Program to a supertype. ”
supertype, usually an abstract class or interface
Program to an interface, not an implementation
● imagine an abstract class Animal, with two concrete
implementations, Dog and Cat.
● Programming to an implementation would be:
● Program to interface would be:
○ We know it is a Dog but we use the animal reference because of
polymorphism
● Even better, rather than hard-coding the instantiation of the
subtype (like new Dog()) into the code,
● assign the concrete implementation object at runtime:
Behaviour
can be set
at runtime
• Behavior variable are declared as INTERFACE TYPE; FlyBehavior and QuackBehavior
Delegate Behavior
● Rather than handling the Quack behavior in
the Duck class
● The Duck class delegates to the object
reference quackBehavior
● Superclass only cares that the object can
quack but how that happens is not important
here
Concrete Subclass
● The subclass inherits the variable from the superclass
○ quackBehavior and the flyBehavior
● Subclass has to set these instance variables
○ Select the concrete implementation
HAS-A Relationship
● Each Duck has-a FlyBehaviour & QuackBehaviour
● This is called composition
● Instead of inheriting the fly & quack behaviours, composing the
two is used
Third design pattern: Favor composition over inheritance
Remarks
• The one constant in software development is change
• Think about your code/product/app to make it flexible,
maintainable, and can cope with changes (extendable)
• Patterns rely on OO concepts & principles