Ultimate Design Patterns - Behavioral Flashcards
What are we going to learn in this course?
How to design re-usable, extensible software
What is not covered in this course?
No algorithms, no loops, no if statments, no logic
These topics are covered in other courses
We are not building an application!
Our focus is on building re-usable, easily extensible software
What must every software engineer working with object oriented systems know?
How to structure classes so they can collaborate
How to design software that can be easily extended
Twenty-three classic design patterns (creational, relational, behavioral) all software engineers must know!
How to design reusable and extensible object-oriented software
Master these!
What has helped Mosh tremendously when learning new frameworks?
Knowing design patterns
Sees these patterns repeated in various frameworks and libraries
Every new syntax looks similar to him!
What are design patterns?
Solutions to repeating features in software design
Design pattern shows us how to structure classes and how they communicate
Example
Undue feature (Memento Pattern) is a repeating feature in software design
What design patterns are covered?

Gang of Four Patterns
23 design patterns across creational, structural and behavioral domains
Creational - different way to create objects
Structural - relationships between objects
Behavioral - communication or interaction between objects

What are some of the benefits to mastering the classic design patterns?
- Can communicate without other developers - express your ideas abstractly using design patterns
- Makes you a better designer - Know how to build reusable and maintainable software no matter the language or framework you use!
- learn new frameworks faster - design patterns are used in different frameworks and languages, knowing them helps you learn them faster!
How should we take this course?
Take it beginning to end
Various principles are discussed in each section
What is a design smell?
overly complicated design
Many moving parts
design patterns applied without context
What is the focus of this course?
The art of designing object oriented software
Patterns ordered to teach us important concepts
What happens if we blindly apply design patterns to our applications?
Going to increase complexity
Now more moving parts
Haven’t solved the problem
Created an overly complicated design
aka “design smell”
What does a real engineer do?
- Try to understand the problem
- Brainstorm various solutions
- Pick the one that best fits the problem
How we should engineer software
Apply design patterns
What are the Behavior Design Patterns?

All about interaction (communication) between classes

What are the Structural Design Patterns?
All about the relationship between classes

How should we apply design patterns?
- Try to understand the problem
- Brainstorm various design pattern solutions
- Pick the design pattern that best fits the problem
What do code monkeys do?
Write code
Not understanding the problem they are trying to solve
What is abusing design patterns?

A few decision making statements in a single place, nothing wrong!
In State pattern, had decision making statements in multiple methods AND to support a new tool had to modify code!
All decision making was in single place, will not have a new state in the future so no maintainability or extensibility issues!
Code is now overly complicated without benefits
More moving parts
Logic spread over two classes!

What did Leonardo DaVinci say?
Simplicity is the ultimate sophistication
What should we not do?

Abuse design patterns!
Use them without understanding the problem, context and the various solutions!
Use them to improve extensibility and maintainability NOT to make complex applications with no additional benefts!

What is a tightly coupled application?
One in which all the classes are dependent on eachother!
If you change one class, cascading changes happen in other classes
Ex. If you get a flat tire, you only replace one tire
Not all the other tires, the engine and the seatbelt
A car is loosely coupled. Each part isn’t dependent on the other parts.
How can we build loosely coupled applications?
Using interfaces!
Components work together but are not dependent on eachother!
Can replace individual parts separately!
What are interfaces?

A contract that specifies the capabilities that a class should provide as services
Highly misunderstood construct in Java and other languages!
Ex. Open a restaurant, need a cheff
Not dependent on a particular cheff, just someone with the particular capabilities
This is a loosely coupled system!
Represent role of a cheff as interface
actual cheffs, classes that implement cheff interface

When should we use an interface vs. abstract class?

allow us to build loosely coupled applications!
Use abstract class if want to provide common code to child classes
methods in an interface are considered abstract (cannot instantiate them) so can omit abstract keyword

What is the open close principle?
Very important!
Open for extension - can add new classes
Closed for modification - cannot change code in classes
Support new feature?
add new classes, test them!
Makes application robust and extensible

What are the three UML relationships?
Inheritance - methods defined in super class
composition - made of another class
dendency - use another class

How can we represent inheritance using UML?
An arrow from child to parent

How is the composition relationship modeled using UML?
An arrow with a diamond ending
Shape is composed of size class
In Shape class, have field called size
What is it?
ex. Car class is composed of wheel class, because every car has four wheels

How do we represent a class in UML?
Top - name of class
middle section - fields (type of field)
below - methods (parameter or return type
- = private
+ = public

How do we represent the dependency relationship?
Means?
Somewhere in Shape class, reference Document class
render method’s parameter is dependent on Document class

What do we use the memento pattern for doing?
Building undue features!
What is the single responsibility principle?
An important principle in OOP
Says:
every class should have a single responsibility
Ex. Restaurant
Waitor only takes order, doesn’t do taxes, shopping, cooking!
To design extensible software in what ways should we design our classes?
Design our claseses such that each class has only a single responsibility.
What is the memento pattern?

Used to implement undue
Originator - Editor
Memento - EditorState
Caretaker - History

How do we implement the memento pattern?

History - keeps track of changes in editor, stores editorState objects
EditorState -
Editor -
.restore(state) takes state object and resets fields based on what is in state

Implement the undue feature using the memento pattern for content, fontName and fontSize.

What is an enum?
A set of constants
What is the problem with this code?

It’s not maintainable and lacks extensibility!
Why?
not easy to maintain and extend = The more tools we add, the more decision making statements will be required and we have to go to different methods and make changes
ex. change mouseDown ( ) and mouseUp ( ) to accomodate a new tool
Soln?
Ploymorphism
What is the state pattern?

Allows an object to behave differently depending on the state

always use meaningful names that fit the domain of your application!
Textbook names are too general.
How do we implement the State Pattern?

Don’t have a long list of decision statements
Code is more maintainable
Can easily extend

When do we use the State pattern?
To implement behaving differently depending on the state of another object
What is an excercise?

What is the problem here?

everytime we change the internals of the class, we get breaking changes!
Changing the internals of a class shouldn’t affect its consumers!
If we replace the original datastructure storing urls we will have breaking changes in our main class
Ex. Two breaking changes in main class by replacing an arrayList with a fixed array internally!

What problem does the iterator pattern solve?
everytime we change the internals of the class, we get breaking changes!
Changing the internals of a class shouldn’t affect its consumers!
Encapsulating breaking changes within a class so that consumers of our class are not affected
Using Iterator Pattern - don’t need to know the internal structure of the class (array, stack, etc.)
hasNext ( ) - returns boolean
next ( ) - returns void
Telling history item - give me another item, give me another item
What’s the problem with this class?

It breaks the single responsibility criteria
It’s responsible for history management
It’s responsible for iteration

How do we solve the single responsibility program?

When createIterator ( ) is called, Iterator object is returned

Programmed to an interface!
What is the iterator pattern?

How can we change this code to implement the iterator pattern?


What are the benefits of the iterator pattern?
- breaking changes are localized to one class - other classes do not break if changes are made to internal structure of class
Can change the internal iterator from List to ArrayIterator!
What is an excercise?

What are the issues with this code?

- Single Responsibility Principle Violation - this class is responsible for storing an image AND compressing an image/applying a filter!
As we support more image processing algorithms, if/else if statements will get very long and hard to maintain!
2. Difficult to extend number of filters - Have to make changes in different parts of class.
The more filters we support, the more bulky our class will become!
OOP SOLN:
Polymorphism!
What is the Strategy Pattern?

Context maintains reference to strategy object
Strategy interface represents an algorithm
Different classes implements the algorithm
We use both patterns to change behavior of objects
Different behaviors are represented by different strategy objects vs. one state object (State Pattern)

What is the difference between the Strategy Pattern and the State Pattern?

Strategy pattern - different behaviors are represented by different strategy objects
State pattern - All behaviors are represented by a subclass of state interface

How can we apply the Strategy Pattern to make this design more extensible and maintainable?

This is open-closed principle!

How can we save the same image in two different file formats?
Update the ImageStorage.store method to take Compressor and Filter Objects (code against interface)
Can pass alternative classes implementing the Interfaces to the method

What is an excercise?

Instead of Filter / Compressor Interfaces create Encryptor Interface w/ multiple implementing classes (64-bit encryption, 32-bit encryption)
What problem does the Template Method Pattern solve?
Code duplication
Solve How?
OOP Inheritance!
Ex. Everytime we create a new task, we have to instantiate a new auditTrail and call the .record method! This is repetative

What is the Template Method Pattern?

Abstract class with a Template Method
or skeleton for an operation
Hooks = default method implementation, childClass can override if required (very common in Java, Javascript, etc.)

Are private methods inherited by sub-classes?

No - private methods are not inherited by subclasses!
if we declare our abstract method as private we won’t be able to over-ride it!
Protected keyword - hides method but makes it available to subclass

How do we implement the Template Method Pattern?

Create an Abstract Class
execute ( ) method - has under-the-hood logic executed everytime + .doExecute ( ) method call which can be polymorphed by each sub-class

What is an excercise using the Template Method Pattern?

What problem does the Command Pattern solve?
Coupling between a sending class and a recieving class
What is the Command Pattern?

Decouple a sender to a reciever
Each request is a command object

What are the benefits to the Command Pattern?
Decouple a sender to a reciever
Each request is a command object
- We can pass them around our code
- We can pass them as arguments to our methods
- We can add them to a list to keep track of all commands executed, redo them, undue
- Can store in a DB and run later
How do we create a container for commands so that multiple commands are executed?
Composite Command
Each task is a command object
can combine them into a composite object

How do we execute undoable commands?

Create Command interface
Create UndoableCommand interface (inherits command)
Implementing class - BoldCommand
Ex. Undo bold text, not save

How can we create an undoable command for a text editor?

Commands - links between GUI and Business logic
HtmlDocument - implements business logic / makeBold ( )
History - keeps track of commands applied
What is an excericise using the Command Pattern?

When do we use the Observer Pattern?
State of object changes and we need to notify other objects of changes!
Used in a lot of frameworks!
Ex. values in excell sheet updated, pie chart and second sheet is automatically updated!
What is the Observer Pattern?

aka“Publish Subscribe Pattern”
follows open-closed pattern! Can add more observers!
DataSource - maintain list of observer objects
update ( ) - polymorphic behavior, different update ( ) method for each concreate implementation
addObserver (obs) - add observer to list of observers
removeObserver (obs) - delete observer from list to dynamically add/remove
notifyObservers ( ) - iterate over observers, where polymorphic behavior, depending on type at runtime, single place to notify all observers about changes!

How do we implement the basic Observer Pattern?


What is the challenge of the push style of Observer Pattern?

Changes are pushed to observer!
Challenge:
It is not extensible without violating the open-closed principle!
If we introduce a new ConcreteObserver (future) may have to go to Observer interface to introduce new fields in class!
It’s not flexible!
Assumes Observers needs same values but some Observers could take different values!
What is the pull style of observer communication?

Observers pull data they need when changes occur
It’s Flexible
Each concrete observer can get data they need
There is coupling, but it’s okay! No zero coupling in software.
Direction of coupling/relationship matters!
Direction of coupling makes it acceptable
How do we implement push method of the Observer Pattern?

How do we implement the pull method of the Observer Pattern?

Coupling but it’s okay!
Introduce a private field of type DataSource
Initialize in Constructor
In update method call .getValue( )
More Flexible!

What is an excercise using the Observer Pattern?

In what situation do we use the Mediator Pattern?
When we have a bunch of objects that need to talk to eachother!
Why is using inheritance to solve the problem not a good solution?

Base classes = ListBox, TextBox, Button
Many dependencies
Logic spread all over the place (different classes)
understanding and maintaining becomes difficult with scale!
Soln:
DialogBox (abstract class) - how objects interact will change from one dialogue box to another
ArticlesDialogBox (concrete class) - where we implement all the logic for how objects interact

What is the Mediator Pattern?

Meditator controls interaction between objects!
Mediator - like dialogue box
Concrete Mediator - articles dialogue box
Colleague - UI Control
ConcreteColleague - List, textbox, button

How can we implement the mediator pattern using the observer pattern?

UIControlObjects (TextBox, Button, etc) = Subject class
ArticleDialogBox = Observer of changes in UIControlObjects

How do we implement the meditator pattern using event handlers (observers)?

What is an excercise using the mediator pattern implemented with the observer pattern?

What is this code doing?

.attach ( ) method requires an implementation of the Observer Interface
Observer Interface is a functional Interface (single method)
The changed ( ) method is polymorphically implemented by each Concrete Observer
A concrete observer can be implemented using an annonymous inner class that implements the Observer Interface
in the anonymous inner classes @changed ( ) method, we can call articleSelected ( ) upon change
This can be replaced by a lambda

When do we use Chain of Responsibility Pattern?

When we need a pipeline (chain of objects) to process a ANY request
Ex. Web server that need to authenticate, log and compress an HTTP request
Solution:
Build a pipline or chain or objects for process a request without having to make changes to single class
Why don’t we want to implement the logic of authentication, logging and compression in the WebServer class?

It would violate the single responsibility principle
Solution:
Authentication Class - logic for authentication
Compressor Class - logic for compression
Logger Class - logic for logging

What problem does the chain of responsibility solve?

Webserver.handle ( ) - logic is very fixed
If we want to change our data processing pipeline steps, have to change the .handle ( ) method!
To add a new step have to change implementation of .handle ( ) method - this violated the Open Closed Principle!
Open for extension, closed for modification!
Soln:
Pipeline of processing objects in a chain
Each object only knows about the next object in the chain

What is the Chain of Command Pattern?
WebServer - talks to handler interface indirectly has reference to first handler in chain (authenticator)

How can we implement Chain of Responsibility Pattern?

System is open to extension, closed to modification
Can add new step anywhere in the chain
Ex. add new Handler called Encryptor
Can build data processing pipelines that follow the open closed principle!

What is an excercise?

What problem does the Visitor Pattern solve?

Allows us to add new operations to an object structure without modifying the item
Ex. HtmlNode interface - if we add new methods to this interface, will then have to go to every concrete implementation and implement the new method! Additionally, in HtmlDocument (dependency on HtmlNode) have to iterate over all objects and call the .newMethod!
This violates Open-Closed Principle!
Also, logic is spread over multiple classes!
Why?
Everytime we want to introduce a new operation, have to make changes to every object in our structure

VP What are the benefits of the Visitor Pattern?

- All logic for an operation is in a single place
- Follows Open-Closed Principle
Beware!
Only use if object structure is stable!
Why?
Everytime we create a new opeartion, have to update the Operation interface and all implementing classes

What is the Visitor Pattern?

Names are Abstract
Key principle:
Allows us to add new operations without changing our object structure
How?
Create new class that implements Operation Interface

How do we implement the Visitor Pattern?


What is an excercise?

How could I deconstruct a feature into design patterns? (Ex. TinderSwipe Feature)
Account Creation - Template Method Pattern
Match History - State Pattern
Matching - Observer Pattern
Messaging -
Data Structure - graph
Prediction - getKthNode
Geolocation - traverse, shortest Path Algorithm