Afghanistan
Albania
Algeria
Andorra
Anguilla
Antigua & Barbuda
Argentina
Armenia
Aruba
Australia
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belgium
Belize
Benin
Bermuda
Bhutan
Bolivia
Bonaire
Bosnia & Herzegovina
Botswana
Brazil
British Indian Ocean Ter
Brunei
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Canada
Canary Islands
Cape Verde
Cayman Islands
Central African Republic
Chad
Channel Islands
Chile
China
Christmas Island
Cocos Island
Colombia
Comoros
Congo
Cook Islands
Costa Rica
Cote D Ivoire
Croatia
Cuba
Curacao
Cyprus
Czech Republic
Denmark
Djibouti
Dominica
Dominican Republic
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Ethiopia
Falkland Islands
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
French Southern Ter
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guinea
Guyana
Haiti
Hawaii
Honduras
Hong Kong
Hungary
Iceland
India
Indonesia
Iran
Iraq
Ireland
Isle of Man
Israel
Italy
Jamaica
Japan
Jordan
Kazakhstan
Kenya
Kiribati
Korea North
Korea South
Kuwait
Kyrgyzstan
Laos
Latvia
Lebanon
Lesotho
Liberia
Libya
Liechtenstein
Lithuania
Luxembourg
Macau
Macedonia
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mexico
Midway Islands
Moldova
Monaco
Mongolia
Montserrat
Morocco
Mozambique
Myanmar
Nambia
Nauru
Nepal
Netherland Antilles
Netherlands (Holland, Europe)
Nevis
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
Norway
Oman
Pakistan
Palau Island
Palestine
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Pitcairn Island
Poland
Portugal
Puerto Rico
Qatar
Republic of Montenegro
Reunion
Romania
Russia
Rwanda
Saipan
Samoa
Samoa American
San Marino
Sao Tome & Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Singapore
Slovakia
Slovenia
Solomon Islands
Somalia
South Africa
Spain
Sri Lanka
St Barthelemy
St Eustatius
St Helena
St Kitts-Nevis
St Lucia
St Maarten
St Pierre & Miquelon
St Vincent & Grenadines
Sudan
Suriname
Swaziland
Sweden
Switzerland
Syria
Tahiti
Taiwan
Tajikistan
Tanzania
Thailand
Togo
Tokelau
Tonga
Trinidad & Tobago
Tunisia
Turkey
Turkmenistan
Turks & Caicos Is
Tuvalu
Uganda
Ukraine
United Arab Emirates
United Kingdom
United States of America
Uruguay
Uzbekistan
Vanuatu
Vatican City State
Venezuela
Vietnam
Virgin Islands (Brit)
Virgin Islands (USA)
Wake Island
Wallis & Futana Is
Yemen
Zaire
Zambia
Zimbabwe
Intro
Design Patterns are
Common architectural approaches
Universally Relevant
Popularized by the Gang of Four (1994) book
Smalltalk
Since translated
C#
Java
Etc.
Internalized in some languages
Observer Pattern
C# "event"
Libraries
Boost.
Your own code!
Organization
100% Practical.
CLion
Heavy use of CLion Autocode
Demos are single files
Run in any DEV environment.
Section coding practice
Unsafe practices used for clarity.
Overuse of public members
No virtual destructors
Pass/return by value
No move operations
Etc.
JetBrains
WebStorm
JavaScript runs on NodeJS
Prerequisites
Object-Oriented Programming
C++
ANSII
11
14
17
Good understanding of OOP
Basic Awareness of NodeJS
JS core isn't OOP, but close enough.
Good understanding of latest JavaScript
Instructor
Dmitri Nesteruk
YouTube
GitHub
S.O.L.I.D. Principles
Overview
Single Responsibility
Open-Closed
Liskov Substitution
Interface Segregation
Dependency Segrigation
Summary
Overview
Robert C. Martin
Principles often used to motivate patterns
Introduced by
Single Responsibility
Separation of concerns.
A class
Should
Do One Thing
Should not
Take on more tasks.
Journal.
Product Journal
Product Journal
Open-Closed
Open to Extention (inheritance)
by inheritance
Closed to modification
Make extensive use of templates
Use virtural methods (interfaces)
Product Filter
Filter
Liskov Substitution
Supertypes
hot-swappable
Subtypes
Solve with a factory
Robert Liskov
Rectangle
Rectangle
Interface Segregation
Don't overload interfaces
Decompose everything to atomic functions
Recompose systems from components.
Build decorators
Printer
Printer
You Ain't Gonna Need It (YAGNI)
Dependency Inversion
High-level Modules
Should not depend on
Low-level Modules
Details
Should depend on
Abstractions
Relationships
So you can change underlying implementation
Interfaces
Base Classes
Concrete Types
Relationships
Relationships
Summary
Classes
Sub base type for a subtype
Don't overburden interfaces
High level modules should be low-level agnostic
Separation of concerns
Open for extension, closed for modification
Exist for one purpose
Gamma Categorization
Erich Gamma 3 patterns
Creational Patterns
Structural Patterns
Behavioral Patterns
Deal with creation
Concerned w/ class memebers
All different, no theme.
Wholesale (single statement)
Explicit (constructor)
Implicit (DI, reflection, etc.)
Piecewise (step-by-step)
Stress good API design
Many patterns are wrappers
Mimic underlying class' interface
Creational
Builder
Factories
Prototype
Singleton
Object Pool
Builder
Overview
Life Without Builders
Builder
Fluent
Groovy-Style
Facets
Excercise 1
Summary
Overview
Motivation
API for constructing modularly.
Single contructor call
Some objects are simple.
Opt for piecewise construction
Having lots of constructor arguments is not productive.
Other objects require a lot of ceremony
Life Without Builder
Inconvienient to build strings from parts?
ostringstream
Builder
Handles building compound objects
Has lots of constructors and add functions
Becomes the built object
Manages lots of parameters
HtmlElement
Advertises its own constructors
Advertizes underlying methods
htmelement
Fluent Interface
Change builder return type
Make a typecast in builder to return root class
BuilderType&
Return *this
operator HtmlElement() const {return root}
from void
Can return by reference or value with pointers
Add a static build() member to root class
Can force use of builders instead of constructors
return {root_name};
Make root private
Use friend class
Returns BuilderClass
Groovy-Style
Construct domain-specific language
uses uniform initialization
Allows you to write html-like syntax in C++ code
html re-example
Facets
Underlying object is super complex
typedef blabityblah self;
Use different builders for different facets
"Builder facade"
Person class
Address info
Employment info
1. Builder Exercise
Make a code builder
Summary
A builder
Is a separate component for building another object
Can have multiple builders for complex objects
To make a fluent builder return "this"
Can Either
Give builder a constructor
Return builder via a static function
Factories
Summary
Point Example
Factory Method
Factory
Inner
Abstract
Functional
Exercise 2
Overview
Overview
Factory
Motivation
Object creation logic becomes too convoluted
Constructor is not descriptive
Object creation can be outsourced to
responsible for the wholesale (not piecewise) creation of objects
Will cover factories and abstract factories
A separate function (Factory Method)
Name mandated by name of containing type
Cannot overload w/ same arguments with different names
Can turn into 'optional parameter hell'
separate class (Factory)
Can create heiarchy of factories
Abstract Factory
Point Example
class Point(x, y)
Could make an enum type flag but...
Rectalinear....or polar?
Need to sub out constructor
Can't have both constructors: both 2 floats.
Need something syntactically sensible.
ruins simplicity
Factory Method
Use static members that return built objects
Actual instructor tucked in private
Can have several, each interpreting parameters differently.
Example
#define USE_MATH_DEFINES for PI
Factory
Separating construction concern.
Lots of options
Call private constructor, return base class.
Construct the factory itself.
Move contructors to their own class
Violates open/closed
Need friend class
Just make all base methods public.
Counts as extention, not modification
Inner Factory
Put factory into base class
Can make a singleton of private factory and expose it.
Factory class link to base isn't user-obvious.
Embedded class
Embedded class chains ::'s
Exposes API structure to user
All base class constructors are private
Solves SOLID issues of open/closed
Can see all of parent class fields and methods
Abstract Factory
Creates families of factories for families of classes
Has a concrete facilitator factory
Can be gathred in any data structure
Polymorphism
Functional Factory
Map is now names -> factories
Separate factory class
make and prepare are now inside functional[] closure
2. Factory Exercize
Person Factory
Summary
Factory
Factory object can take care of creation
Function or a static method
Hierarchies can be used to create related objects
Nested classes have access advantages
Can be external or nested class
Prototype
Overview
Record Keeping
Prototype
Prototype Factory
Prototype via Serialization
Excercise 3
Summary
Overview
Partial or fully initialized object
Make a copy (clone) of for use.
Rquires 'deep copy' support
Clone the prototype and customize it
An existing design is a "prototype"
Iterate on designs
Complex objects (cars?) aren't designed from scratch
Streamline copying ala a factory
Record Keeping
Need to deep-copy the component before changing.
Need to track destruction.
Multiple records reference same component.
Imagine Jane and John live in the same building
Storing address contained in Employee
What if address was a pointer?
Jane = John, then modify
Prototype
Add a (deep) copy constructor to Contact
Prototype is first instance
Move deep copy to Address copy constructor
Make a deep copy of first instance
Modify copy.
Prototype Factory
Stuff the instance into a factory.
Create a global prototype instance of class to copy.
Prototype via Serialization
Write code for serialization/ deserialization
Gets serialization and cloning prototypes
Problem is the pointer.
using boost serialization
No reflection in C/C++ so pointers uh...
Or copy assignment operator
So far have to implement copy constructor by hand.
3. Prototype Exercize
Write a deep copy function.
Summary
To implement a prototype
Then how do you clone the prototype?
Partially construct an object
Customize resulting instance
Store it somewhere
Serialize and deserialize (traverses pointers)
Implement your own deep copy code.
Singleton
Overview
Implementation
Testability
In Dependency Injection
Lifetime in DI Container
Monostate
Multiton
Exercise 4
Summary
Overview
A component that is instantiated only once
Instantiation is expensive
Resists being instantiated again.
Thread saftey
Lazy instantiation
Factories, database repositories, etc.
Provides same instance ot everyone.
Implementation
Make Private
The class IS the object.
Data is private.
Can't instantiate.
Constructor
get/set functions fire the constructor.
Assignment operators
Testability
All tests run on THE singleton.
Unit tests turn into integration tests.
Can't dummy up mock data.
Stuck w/ production data.
Singleton in a Dependency Injection
Depending on get/set details for testing
Wrap with an interface
Singleton implements interface
Have a mock singleton w/ same interface.
Presuming singleton implements interface correctly.
Really just testing the interface.
Be able to test mockup on a switch.
Lifetime in a Dependency Injection
Use contained singletons.
Lifespan affects DI framework.
Monostate
All class storage is static.
Doesn't matter how many instances you make.
All gets are last sets.
Can't inherit a static field.
Don't do this.
Not expecting LIFO behavior
Confusing to user.
Multiton
Restricts the number of instances
Sets up an array of singletons.
Prevents re-initialization on same key.
static map<key, shared_ptr<t>> instances
Sets up a <key, value> database
Routes calls to requested singleton.
get is static.
4. Singleton Exercise
from factory
#include <functional> using namespace std; struct SingletonTester { private: int ncalls = 0; public: template <typename T> bool is_singleton(function<T*()> factory) { int answers[] = {1,0}; return answers[ncalls++]; } };
Hacked the exercise.
No clue how to instantiate.
singleton tester
Summary
Making a 'safe' singleton is easy
Difficult to test
Constructor
Assignment operator
Hide or delete
Use an interface or singleton factory
Use an abstraction.
Structural
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Adapter
Overview
Vector/Raster Demo
Caching
Exercise 5
Summary
Overview
Getting the interface you want
Adapts
From the interface you were given.
From existing interface X
to required interface Y
Vector/Raster Demo
Using outdated MSVS MFC drawing routine
Create a pixels interface
Want to draw vectors from points.
Want to draw rectangles from vectors
Create all the mess in between
Example
Adapter Caching
May have intermediate values that need caching.
Use hashes to lump object data
Need to compare new/old data
If hash matches, don't regenerate.
Store hashes in a map
5. Adapter Coding Exercise
To Rectangle
From Square
Adapt
Summary
To implement adapter
Determine
Use caching and other optimizations
Create a component wich aggregates adaptee (by reference)
API you need
API you have
Intermediate values may pile up.
Bridge
Overview
Pimpl Idiom
Shrink-Wrapped Pimpl
Imlementation
Exercise 6
Summary
Overview
Decouples
Prevents 'Cartesian product' complexity explosion
Relies on inheritance + aggregation
Interface
Implementation
Hierachy
Pimpl Idiom
Contain a class w/i a class
Only interface of outer class is exposed.
Keeps private private.
Interface won't change if core class updated.
All implementation details w/i contained class
Contained class's entire definition is in .cpp
Example
Shrink-Wrapped Pimpl
Create a template pimpl class
std::forward
Generate all the code (folding dual template constructor)
Use a template forwarding constructor.
Use unique_pointer
Provide a pointer to the inner class
Example
Bridge Implemenation
Avoid geometric implementations from crossing interface sets.
Build central object
Parameteterize the other interface set.
Inherit ans specify details
Build down one interface set.
Uses functional refrences.
Example
6. Bridge Coding Exercise
Rendered Shapes
Summary
Decouple
Stronger form of
Encapsulation
Implementation
Hiearchies
Abstraction
Composite
Overview
Geometric Shapes
Neural Networks
Array-Backed Properties
Exercise 7
Summary
Overview
Treat Uniformly
Create compound objects
Aggregate
Individual
Complex drawing objects
components
Mathmatical expressions
Geometric Shapes
Base object is an interface.
Objects also inherit interfac
Group is a container
Enforced by interface.
Containers can recurse.
Same API for objects and groups.
Example.
Neural Networks
Create Neuron struct
Create Neuron layer
Abstract connection types through a common interface.
Inheriting from Neuron.
dual-connected map.
ALl kinds of connection possibilities.
Example
Array-backed Properties
Abilities is now an array
Intersect w/ Proxy
Can now use array functions to math
enum the abilitites (terminated w/ count)
Don't math well.
Attributes for an RPG
Example.
7. Composite Coding
Solution
Support a sum()
Works on one or many
Summary
Composite design pattern treats single and plural uniformly
A single object can masquerade as a collection
C++ uses "duck typing"
Composed or singular need similar | identical behavors
begin { return this;} end {return this +1}
enum types provide begin() and end().
Objects can use others via inheritance | composition
Decorator
Overview
Dynamic
Static
Functional
Exercise 8
Summary
Overview Summary
Adding behavior
Without altering existing code.
Want to keep Open-closed Principle (OPC)
May not have source code.
Two options:
Need to interact w/ existing structures
Want to keep new functionality separate (SRP)
Dynamic
Static
Aggregate the decorated object
Inherit from the decorated object
Dynamic
Make a container class
Contain a reference to the base class
All new behavior is in container
Interpret all original behavior
Can form heiarchies of decorations
Don't have access to underlying API.
Shapes and squares demo
Static
Use mix-in with templates
Define all decorators at compile time.
Can now call base class members directly
Inherit from template argument
use std::forward<Args>
Template types chain together.
Example
Functional
Can also decorate functions
Logging example.
Use lambda functions
function<void()> func;
Make helper function to provide prototype
template <typename R, typename... Args>
Allows infrence of type from arguments.
Exercise 8
Flowers
Facade
Overview
Facade
Summary
Overview Summary
Provide an interface
Over a large, sophisticated body of code.
Simple, easy to use
Several components
Single interface
Balance complexity
Presentation, usability
May optionally expose details to power users.
Facade
Bundles details on auto
presents simple interface
Make a singleton interface
constole example
Flyweight
Overview
Handmade
Boost.Flyweight
Text Formatting
Exercise 9
Summary
Overview Summary
Space optimization
Store common data externally
Avoid all data repetitions.
Associate objects with detailed data
Create some kind of relation.
Ex. MMORG first/last names
Ex. operate on ranges
Handmade Flyweight
Use a std::bimap()
Create a dictionary
Check for data collisions.
Example: User names
Call functions to translate in constructor
Code
Boost.Flyweight
boost::flyweight<string> firstName, lastName;
Otherwise behave like strings
Verify with pointers to data.
Text Formatting
Class FormattedText
How to specify which formats go where?
Use list of ranges instead
Bit complex, but space efficent.
Very inefficient.
Could use a bool array[]
Example Code.
Coding Exercise 9
Can be used to capitalize a word
Provide an interface
Returns a WordToken
indexer operator[ ]
Takes a string "hello world"
Given class Sentence
hello WORLD
Proxy
Overview
Smart Pointers
Property
Virtural
Communication
vs. Decorator
Exercise 10
Summary
Overview Summary
Interface to a resource that may...
Proxy
require logging
expensive to construct
remote
Isolates front end from back end changes
Logging Proxy
Communication
Virtural
Guarding
Property Proxy
Intercept property get/set calls
Build a property proxy
C# idea: properties
getter/setter
Implent operator =
Use a template
Creature Example
Smart Pointers
Looks/behaves as if its a pointer
Enhances functionality
More flexible than a replication
Provides several new typecasts
Don't have to call delete() on object
Bank account example.
Virtual Proxy
Giving appearance of working with object
if (!bmp) then
Don't need the image loaded until we execute drawing
Object may not even be there.
Load file as needed.
Build lazy proxy to defer loading.
bitmap example
Communication Proxy
Returns status as remote process runs.
Building remote pong
Pong: pingable object.
Pingable interface
PingPong Example
Proxy vs. Decorator
Proxy
Decorator
Identical interface
Independent of object
Enhances interface
Aggregates underlying object
Object may not even exist
Coding Exercise 10
Proxy a Person class
If driving while drunk: report 'dead'.
Allowed to drive unless younger than 16
Allow person to drink unless they are younger than 18.
ResponsiblePerson
Behavioral
Chain of Responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State
Strategy
Template Method
Visitor
Null Object
Chain of Responsibility
Overview
Pointer Chain
Broker Chain
Exercise 11
Summary
Summary Overview
Chain of components
Each component can terminate processing the chain.
Optionally having default processing implementation
All get a chance to process a command
Graphical element on a form
Unethical business behavior: who gets blame?
Collectable Card Game Battles
Pointer Chain
Recursive add() function
Single linked list of modifiers
Default behavior is to pass down the chain.
Virtual void function apply/handle()
Modifier takes action then passes down the chain.
Specific modifiers inherit from CreatureModifier
Creature Modifier Example
Broker Chain
Boost Signal
Observer
Mediator (for querries)
Use get_attack() to handle querries
Set up a list of listeners
Querry is a class (what do you want?)
Modifiers are now querry listeners
Chain of responsibility
Exercise 11
Goblins
Goblin +1 def to all other goblins.
Goblin King in play is +1 att all goblins.
Goblin King 3/3
Goblin base att 1, def 1.
Goblin Kings are goblins.
Command
Overview
Command
Undo Operations
Composite Command (Macro)
Exercise 12
Summary
Command Query Separation
Command
Querry
CQS Command Query Separation
Demands action or change
Demands data
In GoF "Command" encapsulates "Querry"
Database contexts
Overview Summary
An object that represents an action and its data
Serialize a sequence of actions (calls)
Want an object that represents an operation.
Can't Undo/Redo
Ordinary C++ statements are perishable.
Macro recording
GUI commands
Command
Want to intercept and log all commands.
Perform calls from w/i command functions.
Run through an array of commands
Bank Account system.
Undo Operation
Add an undo method to the command class
Need a flag in command objects for succeeded or not.
by default: not succeded.
nieve assumption: withdraws and deposits are symmetric.
If not succeded, do not undo.
Succeeded at end of operation.
Rollback plays undos in reverse order.
Composite Command (macro)
Neither command knows if the other failed.
Inherits call and undo.
Create a composite vector of commands
Create dependent command that depends on previous successes.
"money transfer command" is a paired withdraw/deposit
Inherit from vector of commands.
Example
Exercise 12
Create a command executer.
Interpreter
Overview
Handmade Interpreter: Lexing
Handmade Interpreter: Parsing
Building Parsers w/ Boost.spirit
Exercise 13
Summary
Overview Summary
Compilers are interpreters
Separate branch of computer science
lexing: break down into components
parsing: interpreting into meaning
Text input needs to be processed.
There are graphical etc. options to describe programs.
lint, html, xml, etc.
Handmade Interpreter: Parsing
foreach Token
virtural eval()
Define class Element
BinaryOperation
Deal with grammar like ( ).
Using enums for symbol types
Handmade Interpreter: Lexing
Spit text expression into tokens
vector<Tokens> = lex(string)
Define Token object
Build a buffer to assemble words/numbers from characters
Also store source text
Use switch() and .pushback() to build token vector in a loop.
lex()
Boost Spirit Parsers
Build visitor to operate across the tree.
define OO structures.
fusion adapt connects spirit
Build large tree.
spirit parses rule set
Output functions are fired from various visitors
Using a framework streamlines the process.
Exercise 13
Interpret Expressions
Iterator
Overview
Iterators in the Standard Library
Binary Tree Iterator
Tree Iterator w/ Co-routines
Boost Iterator Facade
Exercise 14
Summary
Overview Summary
Facilitates traversal of a data structure
Knows how to move to a different element
Can be used implicitly
Keeps a reference to the current element
Ranged-based for loop
Coroutines
Needed for various data structures
Iterators in the STD Library
for (auto& name: names) needs begin/end returns an iterator.
Operates like a pointer, but not compatible with pointers.
rbegin(names) and rend() for reverse iterators
names.end() points to one beyond the end.
vector <>::iterator it = names.begin();
Binary Tree
Binary Tree Iterator
Need to provide begin/end returning an iterator
Can have multiple iterators per class.
end is a nullptr
Begin is one to the left.
Not using recursion yet.
Build an iterator
Tree Iterator w/ Co-Routines
Used to iterate w/ recursion.
Implementing a generator
Cleaner code with recursion: left, right, self.
using impl
Recurse down let node.
Boost Iterator Facade
Helpful construt for helping you build iterator
Define functions suggested by Boost.
friend class boost::itereator_core_access
boost::iterator_facade <ListIterator, node, boost::forward_teraversal_tag>
Iterator Facade
Exercise 14
Given accumulator argment
Node<T>
Pre-order traversal
Complete an iterator
preorder_traversal()
Exercise
Mediator
Overview
Chat Room
Event Broker
Exercise 15
Summary
Overview Summary
Facilitates communication between components
Create a mediator (singleton)
Have every object refer to it.
Want everyone to talk to a central persistent object.
Component may go in and out of system at any time.
Direct references may be destroyed.
Components are unaware of other components
Chat Room
Chatroom class
Person objects
Mediator may be a singleton.
Many players
chatlog: vector<string>
say(), pm(), recieve()
Code
Event Broker
Observer
Chain of Responsibiliy
Players, coaches generate events
Watching game
EventData interface
Coach, player, audience are observers.
Everyone's listening to a central "game" event broker
Exercise 15
initial value = 0
Participants have a value integer
Handle any number of participants
broadcasters don't hear themselves.
Participants increase value by every message heard.
can say() a value, broadcast to all other participants
Solution
Momento
Overview
Memento
Undo & Redo
Automatic Memento
Exercise 16
Summary
Overview Summary
A tokenized state of the system.
Used to roll back state arbitrarily
Allows system to roll back to old state.
Can go to discrete states.
Immutable, no functionality of its own.
Similar to a Command change, but not every action recorded.
May or may not directly expose state information.
Memento
Momento is immutable.
Make momento state private for security
Friend class back to the system.
Only has one state: balance
System method: restore
Bank account
Undo & Redo
Use if state size is smaller than command recording or more stable.
Doesn't record initial state because not hooked to constructor
Also adds a redo()
Have to manage restores as state changes in the chain
Still has a restore
Allows undo/redo by state not action.
Can make a vector of Momentos
Automatic Memento
Momento causes restore in its destructor.
Is a partial state of the sytem. Single function
Use momento object to control object scope.
Indentation token?
Exercise 16
Support adding, return current token.
Each Token is a referenc to a type with 1 numerical value.
In charge of keeping Tokens
TokenMachine
Challenge: return correct value when pointer target changes.
Twist: momentum given smart pointer
Solution
Observer
Overview
Observer
Observable
Observable w/ Boost.Signals
Dependencies Problem
Thread Safety and Reentrancy
Exercise 17
Summary
Overview Summary
Getting notification when things happen (observable)
Want to listen and be notified
Observable Object does something
Field changes
Some external event occurs
Signal -> slot
Event -> Subscriber
Observer
Observer interface
field_changed()
template <typename T> to listen to
observable has to support observer
Person
Observable
Observable inerface
keep an array of observers
Notify action takes place in the getter/setter
Connect observable/observer in subscribe()
Can also unsubscribe
Observable w/ Boost.Signals
Library for implementing observable/observer
Use lambda to subscribed to signal
lambda is attached as a callback
Signal -> slot
Not thread safe!
field_changed('age',32)
[] (Person2& const ...)
Dependencies Problem.
properties w/ no setter are problematic.
Complex Calculated properties are problematic.
Notify in coponent setters for calculated field value
Need more infrastructure to handle proper notifications.
Thread Saftey and Re-Entrancy
But what if unsubscribe and event has the lock set?
What if callbacks fire on separate threads?
Go to a recursive lock
SaferObservable
Only one observable function can fire at a time.
Stick a lock into all observable functions
scoped_lock
Exercise 17
Rats spawn and die
When swarming each rat attack = nRats
Each rat has an attack value of 1
One or more rats can attack a player
Game
Observe spawn/die events.
Rats.
State
Overview
Classic State Implementation
Handmade State Machine
State Machine with Boost.MSM
Exercise 18
Summary
Overview Summary
An object's behavior is determined by its state
Object transitions from one state to another.
Fun with Finite State Machines
Telephone
Changes in state can be explicit or in response to event
A "State Machine" manages transitions
Could be triggered by an observed event
Classic State Implementation
States control which states they feed to
on state, off state objects
LightSwitch state machine
Obsolete.
On/off override their conjugate
Normally just use an enum for problems this small
Switch a lightswitch on and off
Handmade State Machine
Model with a map<state, vector<pair < trigger, state>> rules
Specify Trigger enum
Fill out rule map by hand/load data
Store state as variable of type enum
More efficient
Using an enum
Model phone state
State Machine with Boost.MSM
Meta State Machine
Using class types for all states
back
front
Defines name machine
Executes state machine
Phone example
Exercise 18
CombinationLock
Canges to error on incorrect sequenc
Changes to open on correct sequence
entered digits are shown and added to status
Locked on startup or lock event.
Combination lock
Test both correct and incorrect uses
Strategy
Overview
Static
Dynamic
Exercise 19
Summary
Overview Summary
Enables exact behavior to be selected (aka "policy")
@ compile time (static)
@ runtime (dynamic)
Decompose algorithm
Lower-level parts, configuration specific
Higher-level parts, general setup.
Reuse for multiple configurations.
Static
Add a template argument
Have to make two objects, one with each strategy.
Can't set output format at runtime.
Not as flexible as dynamic approach
Now have a reference instead of a pointer.
Static list
Dynamic
TextProcessor contains a pointer to strategy list.
Strategy is an interface
html or markdown?
Output list
Actions are virtual functions
Variable activities for different outputs.
Create list in html
Exercise 19
if discriminate negative return as-is
If discrimianant is negative return NaN
Real
2 different Discriminat Strategies
Ordinary
Quadadic formula
Quadradic
Template Method
Overview
Template Method
Exercise 20
Summary
Summary Overview
Defines skeleton of the algorithm
Uses inheritance
Makes use of abstract members
Concrete implementations defined in subclasses
Inheritors override the abstract members
Strategy uses interfaces to express parts.
Algorithms = common parts + specifics
Template Method
Main recipie is in root class
Algorithm defined in vitual functions
All subparts are virtual
Overrides particular functions
Game example
Exercise 20
Creatures can fight each other, reducing health
Cretures have 2 values: attack and Health
Collectable Trading Card Game
Permanent: persists
Damage mechanics is different:
Temporary: returns until creature killed
Battle Card Game
Visitor
Overview
Intrusive
Reflective
Classic (Double Dispatch)
Acrylic
Multimethods
Variant and std::visit
Exercise 21
Summary
Summary Overview
Tool for structure traversal.
For adding conern to an entire heiarchy
Generally need access to non-common aspects
Propagating a single visit() method
Component allowed to traverse entire inheritance heiarchy
Don't break Open/Close and Single Responsibility principle
Want to create an external component
Intrusive
Write new function into tree to handle new concern
Does not scale with big heiarchies.
Breaks Single-Concern
Breaks Open-Closed Principle
Intrusive Visitor
Simple Expression Example
Reflective
Write a new object
Try using dynamic cast.
Creates a huge branching tree.
What if you forget something?
How to print depending on a type?
Can't see private values externally from new object.
Moved printing concern to a different structure.
Classic (Double Dispatch)
Extend heiarchy with a double-dispatch.
Uses *this to trick compiler into typing visit calls.
Create an interface for visitor
Things get complex as visit routines multiply.
Heiarchy implements this->visit
Trick system into evaluate types at compile time.
Starts to look like a strategy
Acyclic
Declaring objects to be visitable w/ interface
Accepting a marker interface
Reveal pointer upon typecheck pass.
Bit more security vs. visiting objects
Overcoming limitatoins of using virtual functions
Every heiarchy element has its own accept.
Example.
Multi-Methods
Perform dispatch on 2 arguments at once.
Use a map of collision types.
Allows multimethods per visitor type
Work on collision scheme in a game
Invoke on functional map.
Using an impl
Game Object
Variant and STD::Visit
Make a visitor to work on an std::variant
Used to be part of Boost
Need to overload operator for every type.
Want to create a seperable printer
Using variant
Number vs. house street name.
Address Book
Exercise 21
ExpressionPrinter
Create a double-dispatch visitor
Avoid all blank spaces in output
Round brackets around addtion only
Over addition, and subtraction.
Expresson Visitor
Course Summary
End of Course
Other Courses at Discount
JavaScript Tools
Uses latest ECMAScript
Methods & Static Methods
Classes & Inheritance
Template strings (interpolation etc.)
Arrow functions (aka "lambda" functions)
Getters/Setters (aka "properties")
Default/Rest Params
Jasmine
Enterprize Patterns?
Principle of least surprize