0% found this document useful (0 votes)
19 views68 pages

Software Design Patterns Overview

Uploaded by

denizgunes061998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views68 pages

Software Design Patterns Overview

Uploaded by

denizgunes061998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

1

>

Software Design Patterns

Dr. Anıl Koyuncu


>GoF Patterns

2
>Pattern Classifications
creational design patterns are design patterns that deal with
object creation mechanisms, trying to create objects in a
manner suitable to the situation.

structural design patterns are design patterns that ease the


design by identifying a simple way to realize relationships
between entities

behavioural design patterns are design patterns that identify


common communication patterns between objects and realize
these patterns

3
>Behavioral design patterns
Chain of responsibility
• A way of passing a request between a chain of objects
Command
• Encapsulate a command request as an object
Interpreter
• A way to include language elements in a program
Iterator
• Sequentially access the elements of a collection
Observer
• A way of notifying change to a number of classes

4
>Behavioral design patterns
State
• Alter an object's behavior when its state changes
Strategy
• Encapsulates an algorithm inside a class
Template method
• Defer the exact steps of an algorithm to a subclass
Visitor
• Defines a new operation to a class without change
Mediator
• Defines simplified communication between classes
Memento
• Capture and restore an object's internal state
5
>Sorting People
A person includes a name, an address, and an ID number. For
example:
• Name: Rutherford B. Hayes
• Address: 17 E William St, Delaware, OH 43015
• ID Number: 001-00-019
People displayed by the application should be sortable based on:
• Name
• Zip Code
• ID Number

6
>Sorting People
A person includes a name, an address, and an ID number. For
example:
• Name: Rutherford B. Hayes
• Address: 17 E William St, Delaware, OH 43015
• ID Number: 001-00-019
People displayed by the application should be sortable based on:
• Name
• Zip Code
• ID Number

How would you implement these


requirements?

7
>Option 1: Conditionals
We already know that conditionals
public void sort(int sortType) {
like this can be a code smell.What
switch(sortType) { are the drawbacks of this solution?
case LAST_NAME:
// sort people by last name
break;
case ZIP_CODE:
The class is not very
// sort people by ZIP code cohesive: it is trying to do
and then street name too many things. The sorting
break; algorithms are likely to be
case ID_NUMBER: complex, resulting in a lot of
// sort people by ID number code
}

In addition, it would be difficult


to add new algorithms without
modifying the code (violates
OCP)

8
>Option 2: Subclassing

What are the drawbacks of this


solution?

The algorithms are hard wired to


the subclasses. This requires
several different versions of the
sorting class that differ only by the
sorting algorithm used.

This makes switching


between algorithms difficult;
a new instance needs to be
create and the data copied
between them.
9
>Strategy Pattern
Intent:
• Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithm vary independently from the
clients that use it

10
>Strategy Pattern Structure Diagram

11
>Defining a Sorting Strategy

public interface PeopleSorter { public class SortByName implements


public void doSort(List<Person> PeopleSorter {
people); public void doSort(List<Person> people) {
} people.sort(
Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));
}
}

an interface to represent a sorting strategy. This a concrete strategy for one of the required
interface will be implemented by any class that can sorting strategies, e.g. sorting people by
sort a list of people. last name and then, if the last names
match, by first name.

12
>Interchangeable Strategies

public class PeopleList {

private PeopleSorter sorter; Modify the sorting class, i.e. PeopleList, so that it
private List<Person> people; is a context on which the sorting strategy can be
changed.
public PeopleList() {
people = new ArrayList<>();
sorter = new SortByName();
}

public void setSorter(PeopleSorter sorter)


{ this.sorter = sorter;
}

public void sort() {


sorter.doSort(people);
}

13
>Interchangeable Strategies

public class PeopleList {

private PeopleSorter sorter;


private List<Person> people; The context will need to aggregate an instance of
the strategy interface...
public PeopleList() {
people = new ArrayList<>();
sorter = new SortByName();
}

public void setSorter(PeopleSorter sorter)


{ this.sorter = sorter;
}

public void sort() {


sorter.doSort(people);
}

14
>Interchangeable Strategies

public class PeopleList {

private PeopleSorter sorter;


private List<Person> people; The context will need to aggregate an instance of
the strategy interface...
public PeopleList() {
people = new ArrayList<>();
sorter = new SortByName();
}
...and provide a method that allows
public void setSorter(PeopleSorter sorter)
external clients to change the strategy
{ this.sorter = sorter;
} at any time.

public void sort() {


sorter.doSort(people);
}

15
>Interchangeable Strategies

public class PeopleList {

private PeopleSorter sorter;


private List<Person> people;

public PeopleList() {
When a client calls the method to
people = new ArrayList<>();
sorter = new SortByName(); sort the list of people, the context
} will delegate the responsibility for
handling the sort to the current
public void setSorter(PeopleSorter sorter) strategy
{ this.sorter = sorter;
}

public void sort() {


sorter.doSort(people);
}

16
>People Sorter Strategy Design

17
>Strategy Pattern
Consequences
• Families of related algorithms
• An alternative to subclassing
• Elimination of conditional statements
• A choice of different implementations of the same behavior (e.g. quicksort
vs. merge sort)
• Clients must be aware of the alternatives to switch between them
• Communication overhead between Context and Strategy
• Increased number of objects in the system

18
>

19
>Clipboard Coding
The word processing application shall allow users to copy the
currently selected text to the system clipboard
• Using a Copy option in the Edit menu.
• Using a keyboard shortcut: CTRL-C
• Using the Copy option in the context menu (right click).
• Using the Copy icon in the toolbar
The application shall allow users to paste the contents of the
system clipboard into the current document
• Using a Paste option in the Edit menu.
• Using a keyboard shortcut: CTRL-V
• Using the Paste option in the context menu (right click).
How might you go about
• Using the Paste icon in the toolbar implementing this
requirement?
20
>Option 1: Embedded Code

public void menuClicked() { Embed the code into each of the


Clipboard clipboard = application.getClipboard(); widgets (buttons, menus, etc.)
String contents = clipboard.getContents();
that can be used to perform the
Document document = application.getDocument();
document.paste(contents);
paste function.
}

public void keyboardShortcutUsed() { What are


Clipboard clipboard = application.getClipboard(); the
String contents = clipboard.getContents(); drawbacks
Document document = application.getDocument();
to this
document.paste(contents);
} solution?

21
>Option 1: Embedded Code

public void menuClicked() {


Clipboard clipboard = application.getClipboard();
The most obvious is code duplication.
String contents = clipboard.getContents();
Document document = application.getDocument();
document.paste(contents);
} A number of custom widgets must
be created by extending buttons,
menu items, etc. This leads to
class explosion and lower cohesion
public void keyboardShortcutUsed() {
Clipboard clipboard = application.getClipboard();
String contents = clipboard.getContents();
Document document = application.getDocument(); There is also a high degree of
document.paste(contents); coupling between the application,
} document, clipboard, and various
widgets

22
>Option 2: A Paste Method

public void paste() {


Clipboard clipboard = getClipboard();
Use extract method to encapsulate
String contents = clipboard.getContents(); the code in a method, and call that
Document document = getDocument(); method from each of the
document.paste(contents); appropriate widgets
}

public void menuClicked() { What are


application.paste(); the
} drawbacks
to this
public void keyboardShortcutUsed() {
application.paste(); solution?
}

23
>Option 2: A Paste Method

public void paste() {


Clipboard clipboard = getClipboard();
String contents = clipboard.getContents();
Document document = getDocument(); Again, a number of custom widgets
document.paste(contents); must be created and coupled with the
} main application. This causes class
explosion and violates single
responsibility
public void menuClicked() {
application.paste();
}

public void keyboardShortcutUsed() {


application.paste();
}

24
>Command Pattern
Intent:
• Encapsulate a request as an object, thereby letting you parameterize
clients with different requests, queue or log requests, and support
undoable operations.

25
>Command Pattern Structure Diagram

26
>A command interface
public interface Action { an interface to represent a command that can be
public void performAction(); executed by the user in the word processing
} application

27
>A command interface
public interface Action { an interface to represent a command that can be
public void performAction(); executed by the user in the word processing
} application

public class Copy implements Action {


Next, create a concrete command to
implement the copy action. private WordProc application;

public void performAction() {


application.copy();
}
}

28
>A command interface
public interface Action { an interface to represent a command that can be
public void performAction(); executed by the user in the word processing
} application

public class Copy implements Action {


Next, create a concrete command to
implement the copy action. private WordProc application;

public void performAction() {


application.copy();
}
}

Create a separate concrete command for each user


action, e.g. paste, save, open, etc. Each will call
some method(s) on a specific receiver, e.g. the
main application class that defines the copy and
29
past methods.
>Generic Widgets
public class Button {

private Action action;


Widgets (buttons, menu items, etc.) that can be
created with an instance of your command
public Button(Action action) { interface.
this.action = action;
}

public void buttonClicked() {


action.performAction();
}

30
>Generic Widgets
public class Button {
When the user interacts with the widget, it invokes
private Action action; the method on its command.
public Button(Action action) {
this.action = action; The widget does not need any information about
}
what the command actually does. It just needs to
public void buttonClicked() { invoke its command.
action.performAction();
}
This means that the same, generic widget can be
reused many times in the application with different
commands.

31
>Copy/Paste Command Design
Each widget (button, menu,
etc.) is the invoker of some
command.

32
>Copy/Paste Command Design
Each concrete command
executes one or more methods
on some receiver, e.g. the
main application.

33
>Copy/Paste Command Design
The invokers do not need to
know anything about the
specific command - only
when to invoke it.

34
>Command Pattern
Consequences
• Decouples the object that invokes an operation from the object that knows
how to perform it.
• Commands are first-class objects that can be manipulated and extended
like any other object.
• Commands can be assembled into composite commands (e.g. macros).
• New commands can be easily added because existing classes do not
need to be changed (similar to Strategy).
• Lots of little command classes.

35
>

36
>Invaders from Space
The game should be as responsive
as possible, and so each time the
user presses one of the control
keys, the game should immediately
respond in some way
• The player uses left and right arrow
keys to move their spaceship in the
corresponding direction.
• They use the spacebar to fire a
single shot at the encroaching aliens.
• If at any time the player presses the
“ESC” key, the game pauses and
they are prompted to quit. Pressing
the “y” key will quit the game. How would you implement these
Pressing the “ESC” key again will requirements?
unpause.
37
>Option 1: Polling
while(true){

try {
When using polling, execution is suspended for
Thread.sleep(INTERVAL); some interval, after which the program checks to
} catch(InterruptedException e) {} see if any significant events have occured.

switch(lastKeyPressed()) {

case LEFT_ARROW: Once any event(s) have been handled, the


moveLeft(); break; program suspends execution again until
case RIGHT_ARROW: the next interval elapses.
moveRight(); break;
case SPACE_BAR:
fire(); break;
case ESC:
togglePause(); break; What are the potential drawbacks of
case Y: this implementation?
checkForQuit(); break;
}
}
38
>Drawbacks of Polling
What happens if more than one event occurs between intervals?
What if no events occur?

• Missed Events - if the polling interval is too long, it is possible that more
than one event will occur between intervals.

• Wasted Cycles - if the polling interval is too short, processing time is


wasted when the thread wakes up to check for events and none have
occurred.

• Duplicate Events - it is possible that the same event may be handled more
than once, e.g. a single press of the left arrow moves the ship 2 or more
times.
39
>Observer Pattern
Intent:
• Define a one-to-many dependency between objects so that when one
object changes state, all its dependents are notified and updated
automatically.

40
>Observer Pattern Structure Diagram

41
>Observing a Subject
public interface KeyListener { an interface to be implemented by any
public void keyPressed(KeyEvent event); observers that should be notified whenever
} a key is pressed on the keyboard.

a KeyEvent class is used to encapsulate the details


about the event (e.g. which key was pressed, how many
times, etc.).

public interface Component {


void register(KeyListener listener); a second interface to be implemented by
void deregister(KeyListener listener); any subject on which a key may be pressed
void notify(KeyEvent event); and that should notify any registered
} observers.

42
>Implement the Subject Interface

public class PlayArea implements Component {


a concrete subject so that interested
private List<KeyListener> listeners =
observers can register to be notified
new ArrayList<>(); when an event occurs.

void register(KeyListener listener) {


listeners.add(listener);
}

void deregister(KeyListener listener) {


listeners.remove(listener);
}

void notify(KeyEvent event) {


for(KeyListener listener : listeners)
{
listener.notify(event);
}
}
}
43
>Implement the Subject Interface

public class PlayArea implements Component {

private List<KeyListener> listeners =


new ArrayList<>();

void register(KeyListener listener) {


listeners.add(listener);
}

void deregister(KeyListener listener) {


listeners.remove(listener);
}

void notify(KeyEvent event) { The concrete subject should call this


for(KeyListener listener : listeners)
method to notify its observers
{
listener.notify(event); immediately any time a key is
} pressed.
}
}
44
>Implement the Observer Interface

public class PlayerActionHandler implements


KeyListener { a concrete observer that
includes the code that
public void keyPressed(KeyEvent event) { should be executed each
switch(event.getKeyCode()) { and every time a key is
case LEFT_ARROW: pressed
moveLeft(); break;
case RIGHT_ARROW:
moveRight(); break;
// and so on...
}
}

45
>Implement the Observer Interface

KeyListener listener = new PlayerActionHandler(); an instance of the concrete


Component playArea = new PlayArea(); observer and register it with
playArea.register(listener); the concrete subject.

The concrete subject will notify the concrete


observer immediately whenever a key is pressed. No
polling needed!

46
>Invaders from Space Observer Design

47
>Observer Pattern
Consequences
• Abstract coupling is used so that the Concrete Subject is not coupled with
Concrete Observers (and vice versa).
• Updates a broadcast to any interested observers.
• Cascading updates may occur if/when one observer modifies the subject.

48
>

49
>Superb Plumber Siblings
 the player avatar starts in its small form.
• Contact with an enemy results in losing a life (character death).
• Acquiring a mushroom awards 1000 points and changes the player
avatar to its superb form.
• Acquiring a fire flower awards 1000 points and changes the player
avatar to its shooter form.
 While in superb form.
• Contact with an enemy changes the player avatar to its small form.
• Acquiring a mushroom awards 1000 points.
• Acquiring a fire flower awards 1000 points and changes the player
avatar to its shooter form. How would you
 While in shooter form. implement these
requirements?
• Contact with an enemy changes the player avatar to its small form.
• Pressing the fire button shoots a fireball.
• Acquiring a mushroom awards 1000 points
• Acquiring a fire flower awards 1000 points.

50
>Superb Plumber Siblings State Diagram
Number of ways that the
different states of the
player avatar may be
handled
○ Small Form
○ Superb Form
○ Shooter Form

Different events may cause


transitions from one state to
another.
○ Some events include an
action list, e.g. awarding 1000
points.
○ There are no guard
conditions in this diagram.

51
>Option 1: Conditionals
Every method on the player avatar changes behavior
public void enemyContacted() { depending on the current state using a conditional to
switch(currentState) {
determine which code to execute, e.g. what to do when
case SMALL_FORM:
loseALife();
the player contacts an enemy.
break;
case SUPERB_FORM:
case SHOOTER_FORM: What are the major drawbacks of this approach?
currentState = SMALL_FORM;
shrinkAvatar();
break;
}
}

52
>Option 1: Conditionals

public void enemyContacted() { One massive class that contains all of the behavior for all
switch(currentState) { of the possible states is not very cohesive.
case SMALL_FORM:
loseALife();
break;
case SUPERB_FORM:
Adding new states (like invincibility!) requires modifying
case SHOOTER_FORM: all of the state-dependent methods (OCP).
currentState = SMALL_FORM;
shrinkAvatar();
break;
}
}

All possible states and behavior are mixed together. This


makes it possible for the object to be in an inconsistent
state where some methods execute as though the system
is in one state and others execute as though it is in a
different state.

53
>Option 2: Subclassing

An abstract class for the player avatar,


and a different subclass for each
possible state.

54
>Option 2: Subclassing

What decides which to instantiate?


What controls the transitions from
one instance to another when an
event occurs?

How is player state (like score


and remaining lives) copied
from one to the other?

55
>State Pattern
Intent:
• Allow an object to alter its behavior when its internal state changes. The
object will appear to change its class.

56
>State Pattern Structure Diagram

57
>a State Interface

interface Form { an interface that represents the state that the player avatar
may be in
void handleEnemy();
void handleMushroom();
void handleFireFlower(); define a method for each of the behaviors that changes
void handleFireButton(); based on the current state.

58
>a Context

public class PlayerAvatar {


private Form currentForm; The context contains all of the state required
int score; for the player avatar including an instance of
int lives; the state interface that represents the current
state.
void setForm(Form form) {
currentForm = form;
}
public void enemyContacted() {

currentForm.handleEnemy();
}
public void mushroomAcquired() {
currentForm.handleMushroom();
}
// and so on...
}

59
>a Context

public class PlayerAvatar {


private Form currentForm;
int score;
int lives;
The context also provides a (usually
void setForm(Form form) { protected) method used to change the current
currentForm = form; state.
}
public void enemyContacted() {

currentForm.handleEnemy();
}
public void mushroomAcquired() {
currentForm.handleMushroom();
}
// and so on...
}

60
>a Context

public class PlayerAvatar {


private Form currentForm;
int score;
int lives;
In each method that changes
void setForm(Form form) { behavior depending on the
currentForm = form; current state, the context
} delegates to the current
public void enemyContacted() { state.

currentForm.handleEnemy();
}
public void mushroomAcquired() {
currentForm.handleMushroom();
}
// and so on...
}

61
>Concrete States

public class SmallForm implements Form {


a concrete state for each of the possible
private final PlayerAvatar avatar; states that the player avatar may be in.

SmallForm(PlayerAvatar avatar) {
this.avatar = avatar;
}

public void handleEnemy() {


avatar.loseALife();
}

public void handleMushroom() {


avatar.score += 1000;
avatar.grow();
avatar.setForm(
new SuperbForm(avatar)); }
// and so on...
}

62
>Concrete States

public class SmallForm implements Form {

private final PlayerAvatar avatar;

SmallForm(PlayerAvatar avatar) {
this.avatar = avatar; the concrete state has a reference to the
} context which is used to change the state
and/or call methods on the context.
public void handleEnemy() {
avatar.loseALife();
}

public void handleMushroom() {


avatar.score += 1000;
avatar.grow();
avatar.setForm(
new SuperbForm(avatar)); }
// and so on...
}

63
>Concrete States

public class SmallForm implements Form {

private final PlayerAvatar avatar;

SmallForm(PlayerAvatar avatar) {
this.avatar = avatar; the concrete state has a reference to the
} context which is used to change the state
and/or call methods on the context.
public void handleEnemy() {
avatar.loseALife();
}

public void handleMushroom() { Some of the methods on the concrete


avatar.score += 1000; state may cause the context to transition
avatar.grow(); to another state.
avatar.setForm(
new SuperbForm(avatar)); }
// and so on...
}

64
>Superb Plumber Siblings State Design

65
>State Pattern
Consequences
• State-specific behavior is partitioned into separate objects.
• State-transitions become explicit and the context is protected from
inconsistent internal states.
• Managing the transition between states can be messy or tricky.
• The context may be a “state holder.”
• Class Explosion (lots of states).

66
>

67
>

68

You might also like