SlideShare une entreprise Scribd logo
1  sur  26
JS DESIGN
PATTERNS
& REACTIVE
PROGRAMMING
The implementation of a design pattern per day
keeps the angry developer away
-Old Chinese proverb
WHY USE ?
➤ easy way to refer to a very specific implementation of code
➤ can help to thwart minor issues that can create major problems later down the road
➤ Patterns exemplify a level of sophistication that can provide both performance boosts
and reduction of excess memory usage
➤ Patterns established through rigorous testing which means they are, for the most
part, "tried and true" and do aid in solving a particular type of problem
DESIGN PATTERN
CATEGORIES
This category deals directly with object initialisation procedures focusing on the creation of
situation-specific objects.
It works to solve the problem of how objects are created by adding a layer to this process
CREATIONAL DESIGN PATTERNS
image credit: https://addyosmani.com/resources/essentialjsdesignpatterns/book/#categoriesofdesignp
SINGLETON
➤ Advantages
➤ Reduced memory footprint
➤ Single point of access
➤ Delayed initialisation that prevents
instantiation until required
➤ Disadvantages
➤ Once instantiated, they're hardly ever “reset"
➤ Harder to unit test and sometimes introduces
hidden dependencies
var mySingleton = ( function( window, undefined ) {
var instance = null;
// revealing module pattern that handles initialization of our new module
function initializeNewModule() {
function myMethod() {
alert( 'my method' );
}
function myOtherMethod() {
alert( 'my other method' );
}
return {
someMethod : myMethod,
someOtherMethod : myOtherMethod
};
}
// handles the prevention of additional instantiations
function getInstance() {
if( ! instance ) {
instance = new initializeNewModule();
}
return instance;
}
return {
getInstance : getInstance
};
} )( window );
// example usage
mySingleton.getInstance().someMethod(); // alerts "my method"
mySingleton.getInstance().someOtherMethod(); // alerts "my other method"
FACTORY
➤ Advantages
➤ Makes complex object creation easy through an
interface that can bootstrap this process for you
➤ Great for generating different objects based on
the environment
➤ Practical for components that require similar
instantiation or methods
➤ Great for decoupling components by
bootstrapping the instantiation of a different
object to carry out work for particular instances
➤ Disadvantages
➤ Unit testing can be difficult as a direct
result of the object creation process being
hidden by the factory methods
function CarDoor( options ) {
this.color = options.color || 'red';
this.side = options.side || 'right';
this.hasPowerWindows = options.hasPowerWindows || true;
}
function CarSeat( options ) {
this.color = options.color || 'gray';
this.material = options.material || 'leather';
this.isReclinable = options.isReclinable || true;
}
function CarPartFactory() {}
CarPartFactory.prototype.createPart = function createCarPart( options ) {
var parentClass = null;
if( options.partType === 'door' ) {
parentClass = CarDoor;
} else if( options.partType === 'seat' ) {
parentClass = CarSeat;
}
if( parentClass === null ) {
return false;
}
return new parentClass( options );
}
// example usage
var myPartFactory = new CarPartFactory();
var seat = myPartFactory.createPart( {
partType : 'seat',
material : 'leather',
color : 'blue',
isReclinable : false
} );
// outputs: true
console.log( seat instanceof CarSeat );
// outputs a CarSeat object with material "leather", color "blue", isReclinable "false"
console.log( seat );
REVEALING MODULE
➤ Advantages
➤ Cleaner approach for developers
➤ Supports private data
➤ Less clutter in the global namespace
➤ Localisation of functions and variables through
closures
➤ The syntax of our scripts are even more consistent
➤ Explicitly defined public methods and variables which
lead to increased readability
➤ Disadvantages
➤ Private methods and functions lose extendability
since they are unaccessible
➤ It's harder to patch public methods and variables that
are referred to by something private
var MyModule = ( function( window, undefined ) {
function myMethod() {
alert( 'my method' );
}
function myOtherMethod() {
alert( 'my other method' );
}
// explicitly return public methods when this object is instantiated
return {
myMethod : myMethod,
};
} )( window );
// example usage
MyModule.myMethod(); // alerts "my method"
MyModule.myOtherMethod(); // undefined
STRUCTURAL DESIGN PATTERNS
This category is concerned
with object composition and
to identify simple ways to
realise relationships
between different objects.
It helps ensure that when
one part of a system
changes, the entire structure
of the system doesn't need
to do the same.
image credit: https://addyosmani.com/resources/essentialjsdesignpatterns/book/#categoriesofdesignp
THE FACADE
PATTERN➤ Advantages
➤ Enhances security for your web application
➤ Works well in combination with other
patterns
➤ Makes it easy to patch internals
➤ Provides a simpler public interface
➤ Proven useful for other major libraries such
as jQuery
➤ Disadvantages
➤ Performance impact
// a facade that masks the various browser-specific methods
function addEvent( element, event, callback ) {
if( window.addEventListener ) {
element.addEventListener( event, callback, false );
} else if( document.attachEvent ) {
element.attachEvent( 'on' + event, callback );
} else {
element[ 'on' + event ] = callback;
}
}
DECORATOR
➤ Advantages
➤ Can be used transparently
➤ Is fairly flexible
➤ Avoids the need to rely on large numbers of
subclasses to get the same benefits.
➤ Disadvantages
➤ Can complicate the application architecture if
poorly managed
➤ Introduces many small, but similar objects
into our namespace
// A vehicle constructor
function Vehicle( vehicleType ){
// some sane defaults
this.vehicleType = vehicleType || "car";
this.model = "default";
this.license = "00000-000";
}
// Test instance for a basic vehicle
var testInstance = new Vehicle( "car" );
console.log( testInstance );
// vehicle: car, model:default, license: 00000-000
var truck = new Vehicle( "truck" );
// New functionality we're decorating vehicle with
truck.setModel = function( modelName ){
this.model = modelName;
};
truck.setColor = function( color ){
this.color = color;
};
// Test the value setters and value assignment works correctly
truck.setModel( "CAT" );
truck.setColor( "blue" );
console.log( truck );
// vehicle:truck, model:CAT, color: blue
// Demonstrate "vehicle" is still unaltered
var secondInstance = new Vehicle( "car" );
console.log( secondInstance );
// vehicle: car, model:default, license: 00000-000
BEHAVIOURAL DESIGN PATTERNS
Behavioural design patterns focus on improving or streamlining through the identification of
common communication patterns between various objects
image credit:
https://addyosmani.com/
resources/essentialjsdes
ignpatterns/book/#categ
oriesofdesignpatterns
THE MEDIATOR
PATTERNThis pattern usually implements a single object that
becomes a shared resource through all of the different
pieces of an application.
➤ Advantages
➤ Reduces the communication relationship from
"many-to-many" to “many-to-one"
➤ Helps us pinpoint dependencies
➤ Excellent at decoupling objects which often
promotes smaller, reusable components
➤ Disadvantages
➤ Introduces a single point of failure
➤ When modules communicate back and forth using a
mediator pattern, it tends to become cumbersome
and usually results in a clear performance hit
var Mediator = ( function( window, undefined ) {
function Mediator() {
this._topics = {};
}
Mediator.prototype.subscribe = function mediatorSubscribe( topic, callback ) {
if( ! this._topics.hasOwnProperty( topic ) ) {
this._topics[ topic ] = [];
}
this._topics[ topic ].push( callback );
return true;
};
Mediator.prototype.unsubscribe = function mediatorUnsubscriBe( topic, callback ) {
if( ! this._topics.hasOwnProperty( topic ) ) {
return false;
}
for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) {
if( this._topics[ topic ][ i ] === callback ) {
this._topics[ topic ].splice( i, 1 );
return true;
}
}
return false;
};
Mediator.prototype.publish = function mediatorPublish() {
var args = Array.prototype.slice.call( arguments );
var topic = args.shift();
if( ! this._topics.hasOwnProperty( topic ) ) {
return false;
}
for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) {
this._topics[ topic ][ i ].apply( undefined, args );
}
return true;
};
return Mediator;
} )( window );
// example subscriber function
var listener = function ExampleListener( myVariable ) {
console.log( myVariable );
};
// example usages
var myMediator = new Mediator();
myMediator.subscribe( 'some event', listener );
myMediator.publish( 'some event', 'foo bar' ); // console logs "foo bar"
THE OBSERVER
PATTERNThis pattern implements a single object (the subject) that
maintains a reference to a collection of objects (known as
"observers") and broadcasts notifications when a change to
state occurs.
➤ Advantages
➤ Helps us pinpoint dependencies
➤ Excellent at decoupling objects which often promotes
smaller, reusable components
➤ Disadvantages
➤ Checking the integrity of your application can become
difficult
➤ Requires deeper-level thinking of the relationship
between the various components of an application
➤ Switching a subscriber from one publisher to another
can be costly
// build the Subject base class
var Subject = ( function( window, undefined ) {
function Subject() {
this._list = [];
}
// this method will handle adding observers to the internal list
Subject.prototype.observe = function observeObject( obj ) {
console.log( 'added new observer' );
this._list.push( obj );
};
Subject.prototype.unobserve = function unobserveObject( obj ) {
for( var i = 0, len = this._list.length; i < len; i++ ) {
if( this._list[ i ] === obj ) {
this._list.splice( i, 1 );
console.log( 'removed existing observer' );
return true;
}
}
return false;
};
Subject.prototype.notify = function notifyObservers() {
var args = Array.prototype.slice.call( arguments, 0 );
for( var i = 0, len = this._list.length; i < len; i++ ) {
this._list[ i ].next.apply( null, args );
}
};
return Subject;
} )( window );
// setup an object that fetchs stocks
function StockGrabber() {
var subject = new Subject();
this.addObserver = function addObserver( newObserver ) {
subject.observe( newObserver );
};
this.removeObserver = function removeObserver( deleteObserver ) {
subject.unobserve( deleteObserver );
};
this.fetchStocks = function fetchStocks() {
// fake fetching the stocks
var stocks = {
aapl : 167.00,
goog : 243.67,
msft : 99.34
};
// notify our observers of the stock change
subject.notify( stocks );
};
}
// define a couple of different observers
var StockUpdaterComponent = {
next : function() {
console.log( '"next" called on StockUpdater with: ', arguments
);
}
};
var StockChartsComponent = {
next : function() {
console.log( '"next" called on StockCharts with: ', arguments
);
}
};
// example usage
var stockApp = new StockGrabber();
stockApp.addObserver( StockUpdaterComponent );
stockApp.fetchStocks(); // console logs: "next" called on
StockUpdater with...
stockApp.addObserver( StockChartsComponent );
stockApp.fetchStocks(); // console logs: "next" called on
StockUpdater with... "next" called on StockCarts with...
stockApp.removeObserver( StockUpdaterComponent );
stockApp.fetchStocks(); // console logs: "next" called on
StockCharts with...
stockApp.removeObserver( StockChartsComponent );
stockApp.fetchStocks(); // does nothing; no observers
THE OBSERVER
PATTERNThis pattern implements a single object (the subject) that
maintains a reference to a collection of objects (known as
"observers") and broadcasts notifications when a change to
state occurs.
➤ Advantages
➤ Helps us pinpoint dependencies
➤ Excellent at decoupling objects which often promotes
smaller, reusable components
➤ Disadvantages
➤ Checking the integrity of your application can become
difficult
➤ Requires deeper-level thinking of the relationship
between the various components of an application
➤ Switching a subscriber from one publisher to another
can be costly
THE ITERATOR
PATTERNProvide a way to access the elements of an
aggregate object sequentially without exposing its
underlying representation
➤ Advantages
➤ provides a standardised way to iterate any
iterable object
➤ allows developers to design looping
constructs that are far more flexible and
sophisticated
➤ Disadvantages
➤ needs custom implementation
➤ hard to generate consistency do to lack of
native JS implementation of Interfaces
var Iterator = function(items) {
this.index = 0;
this.items = items;
}
Iterator.prototype = {
first: function() {
this.reset();
return this.next();
},
next: function() {
return this.items[this.index++];
},
hasNext: function() {
return this.index <= this.items.length;
},
reset: function() {
this.index = 0;
},
each: function(callback) {
for (var item = this.first(); this.hasNext(); item = this.next()) {
callback(item);
}
}
}
// log helper
var log = (function() {
var log = "";
return {
add: function(msg) { log += msg + "n"; },
show: function() { alert(log); log = ""; }
}
})();
function run() {
var items = ["one", 2, "circle", true, "Applepie"];
var iter = new Iterator(items);
// using for loop
for (var item = iter.first(); iter.hasNext(); item = iter.next()) {
log.add(item);
}
log.add("");
// using Iterator's each method
iter.each(function(item) {
log.add(item);
});
log.show();
}
JS
REACTIVE
PROGRAM
MING“Everything is a stream”
BIG QUESTIONS
➤ What is Reactive Programming?
➤ A programming paradigm oriented around data flows and the propagation of change. This means that it
should be possible to express static or dynamic data flows with ease in the programming languages used,
and that the underlying execution model will automatically propagate changes through the data flow.
➤ Why should I consider adopting RP?
➤ It raises the level of abstraction of your code so you can focus on the interdependence of events that define
the business logic, rather than having to constantly fiddle with a large amount of implementation details.
Code in RP will likely be more concise
➤ What is a stream?
➤ Event buses or your typical click events are really an asynchronous event stream, on which you can observe
and do some side effects. Reactive is that idea on steroids. You are able to create data streams of anything,
not just from click and hover events. Streams are cheap and ubiquitous, anything can be a stream: variables,
user inputs, properties, caches, data structures, etc. You can listen to that stream and react accordingly
A HTTP REQUEST OBSERVABLE
let requestStream = Rx.Observable.just('https://api.github.com/users');
let responseStream = requestStream
.flatMap((requestUrl) => {
return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
});
responseStream.subscribe((response) => {
// render `response` to the DOM however you wish
});
➤ What are we doing?
1. we create a simple stream from a url string
2. we subscribe / observe that stream
3. we get every event on that stream ( requestUrl ) and
make an http get request
4. then we “observe”(make a observable object) from
the promise
5. pass that to the responseStream variable
6. observe(subscribe) to the result of the http call
A DOM EVENT OBSERVABLE
let domElement = document.querySelector('#someId');
let domElementObs =
Rx.Observable.fromEvent(domElement, 'blur')
.map((ev)=>ev.target.value);
domElementObs.subscribe(ev => {
console.log(ev);
});
➤ What are we doing?
1. we are creating an observable stream from the dom
element’s “blur” event
2. we map / transform that event data so that we only
get the input’s value
3. we subscribe / observe to the event stream and
process the data.
FLATMAP IS YOUR BEST FRIEND
let source =
Rx.Observable.interval(100).take(10)
.flatMap(
(res) => {
return Rx.Observable.timer(500).map(()=>res*2)
}
);
source.subscribe(x=>console.log(x));
➤ Why?
1. It transforms multiple streams of observables into a
single observable
2. It does that by applying a rule defined by you
3. It helps you keep things clean and easy to
understand
A TYPEAHEAD SEARCH BOX
function main() {
var $input = $('#textInput'),
$results = $('#results');
var keyup = Rx.Observable.fromEvent($input, 'keyup')
.map(function (e) {
return e.target.value;
})
.filter(function (text) {
return text.length > 2;
})
.debounce(750)
.distinctUntilChanged();
var searcher = keyup.flatMapLatest(searchWikipedia);
searcher.subscribe(
function (data) {
$results
.empty()
.append($.map(data[1], function (v) {
return $('<li>').text(v);
}));
},
function (error) {
$results
.empty()
.append($('<li>'))
.text('Error:' + error);
});
}
➤ What are we doing?
1. we are creating an observable stream from the dom
element’s “keyup” event
2. we filter that event data so that we only get values
longer than 2 keys
3. we pause for 0.75 s
4. and do all this only if the value has changed
5. use flatMap to pass the input to the http method
6. subscribe to the stream and output the result to the
dom
OBSERVABLE AND/OR OPERATIONS
// Get elements
let weightSliderElem = document.querySelector('#weight-slider');
let weightTextElem = document.querySelector('#weight-text');
let heightSliderElem = document.querySelector('#height-slider');
let heightEditTextElem = document.querySelector('#height-edit-text');
let heightTextElem = document.querySelector('#height-text');
let bmiTextElem = document.querySelector('#bmi-text');
// Observables
let weight = Rx.Observable.fromEvent(weightSliderElem, 'input')
.map(ev => ev.target.value)
.startWith(weightSliderElem.value);
let height1 = Rx.Observable.fromEvent(heightSliderElem, 'input')
.map(ev => ev.target.value)
.startWith(heightSliderElem.value);
let height2 = Rx.Observable.fromEvent(heightEditTextElem, 'input')
.map(ev => parseInt(ev.target.value))
.startWith(heightEditTextElem.value);
let height = height1.merge(height2);
let bmi = weight.combineLatest(height, (w,h) => w/(h*h*0.0001));
// Subscriptions
weight.subscribe(x => weightTextElem.innerHTML = x);
height1.subscribe(x => heightTextElem.innerHTML = x);
bmi.subscribe(x => bmiTextElem.innerHTML = x);
➤ What are we doing?
1. We start by creating observable streams from dom
events
2. We create the height variable by combining multiple
observable streams into a new observable
3. We create a new observable variable by using
comblineLatest() method that emits a value ,filtered
from the source observables latest emitted values.
4. We then handle the display logic.
Code sample from André Staltz
FURTHER READING AND DOCUMENTATION
SOURCES➤ Best intro to RxJS in the world: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
➤ The documentation: http://reactivex.io/documentation/observable.html
➤ Github page: https://github.com/Reactive-Extensions/RxJS
➤ egghead.io: https://egghead.io/technologies/rx
➤ And … google it
QUESTIONS PLS…

Contenu connexe

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

En vedette

How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
ThinkNow
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 

En vedette (20)

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 

JS Design Patterns & Reactive Programming

  • 2. The implementation of a design pattern per day keeps the angry developer away -Old Chinese proverb
  • 3. WHY USE ? ➤ easy way to refer to a very specific implementation of code ➤ can help to thwart minor issues that can create major problems later down the road ➤ Patterns exemplify a level of sophistication that can provide both performance boosts and reduction of excess memory usage ➤ Patterns established through rigorous testing which means they are, for the most part, "tried and true" and do aid in solving a particular type of problem
  • 5. This category deals directly with object initialisation procedures focusing on the creation of situation-specific objects. It works to solve the problem of how objects are created by adding a layer to this process CREATIONAL DESIGN PATTERNS image credit: https://addyosmani.com/resources/essentialjsdesignpatterns/book/#categoriesofdesignp
  • 6. SINGLETON ➤ Advantages ➤ Reduced memory footprint ➤ Single point of access ➤ Delayed initialisation that prevents instantiation until required ➤ Disadvantages ➤ Once instantiated, they're hardly ever “reset" ➤ Harder to unit test and sometimes introduces hidden dependencies var mySingleton = ( function( window, undefined ) { var instance = null; // revealing module pattern that handles initialization of our new module function initializeNewModule() { function myMethod() { alert( 'my method' ); } function myOtherMethod() { alert( 'my other method' ); } return { someMethod : myMethod, someOtherMethod : myOtherMethod }; } // handles the prevention of additional instantiations function getInstance() { if( ! instance ) { instance = new initializeNewModule(); } return instance; } return { getInstance : getInstance }; } )( window ); // example usage mySingleton.getInstance().someMethod(); // alerts "my method" mySingleton.getInstance().someOtherMethod(); // alerts "my other method"
  • 7. FACTORY ➤ Advantages ➤ Makes complex object creation easy through an interface that can bootstrap this process for you ➤ Great for generating different objects based on the environment ➤ Practical for components that require similar instantiation or methods ➤ Great for decoupling components by bootstrapping the instantiation of a different object to carry out work for particular instances ➤ Disadvantages ➤ Unit testing can be difficult as a direct result of the object creation process being hidden by the factory methods function CarDoor( options ) { this.color = options.color || 'red'; this.side = options.side || 'right'; this.hasPowerWindows = options.hasPowerWindows || true; } function CarSeat( options ) { this.color = options.color || 'gray'; this.material = options.material || 'leather'; this.isReclinable = options.isReclinable || true; } function CarPartFactory() {} CarPartFactory.prototype.createPart = function createCarPart( options ) { var parentClass = null; if( options.partType === 'door' ) { parentClass = CarDoor; } else if( options.partType === 'seat' ) { parentClass = CarSeat; } if( parentClass === null ) { return false; } return new parentClass( options ); } // example usage var myPartFactory = new CarPartFactory(); var seat = myPartFactory.createPart( { partType : 'seat', material : 'leather', color : 'blue', isReclinable : false } ); // outputs: true console.log( seat instanceof CarSeat ); // outputs a CarSeat object with material "leather", color "blue", isReclinable "false" console.log( seat );
  • 8. REVEALING MODULE ➤ Advantages ➤ Cleaner approach for developers ➤ Supports private data ➤ Less clutter in the global namespace ➤ Localisation of functions and variables through closures ➤ The syntax of our scripts are even more consistent ➤ Explicitly defined public methods and variables which lead to increased readability ➤ Disadvantages ➤ Private methods and functions lose extendability since they are unaccessible ➤ It's harder to patch public methods and variables that are referred to by something private var MyModule = ( function( window, undefined ) { function myMethod() { alert( 'my method' ); } function myOtherMethod() { alert( 'my other method' ); } // explicitly return public methods when this object is instantiated return { myMethod : myMethod, }; } )( window ); // example usage MyModule.myMethod(); // alerts "my method" MyModule.myOtherMethod(); // undefined
  • 9. STRUCTURAL DESIGN PATTERNS This category is concerned with object composition and to identify simple ways to realise relationships between different objects. It helps ensure that when one part of a system changes, the entire structure of the system doesn't need to do the same. image credit: https://addyosmani.com/resources/essentialjsdesignpatterns/book/#categoriesofdesignp
  • 10. THE FACADE PATTERN➤ Advantages ➤ Enhances security for your web application ➤ Works well in combination with other patterns ➤ Makes it easy to patch internals ➤ Provides a simpler public interface ➤ Proven useful for other major libraries such as jQuery ➤ Disadvantages ➤ Performance impact // a facade that masks the various browser-specific methods function addEvent( element, event, callback ) { if( window.addEventListener ) { element.addEventListener( event, callback, false ); } else if( document.attachEvent ) { element.attachEvent( 'on' + event, callback ); } else { element[ 'on' + event ] = callback; } }
  • 11. DECORATOR ➤ Advantages ➤ Can be used transparently ➤ Is fairly flexible ➤ Avoids the need to rely on large numbers of subclasses to get the same benefits. ➤ Disadvantages ➤ Can complicate the application architecture if poorly managed ➤ Introduces many small, but similar objects into our namespace // A vehicle constructor function Vehicle( vehicleType ){ // some sane defaults this.vehicleType = vehicleType || "car"; this.model = "default"; this.license = "00000-000"; } // Test instance for a basic vehicle var testInstance = new Vehicle( "car" ); console.log( testInstance ); // vehicle: car, model:default, license: 00000-000 var truck = new Vehicle( "truck" ); // New functionality we're decorating vehicle with truck.setModel = function( modelName ){ this.model = modelName; }; truck.setColor = function( color ){ this.color = color; }; // Test the value setters and value assignment works correctly truck.setModel( "CAT" ); truck.setColor( "blue" ); console.log( truck ); // vehicle:truck, model:CAT, color: blue // Demonstrate "vehicle" is still unaltered var secondInstance = new Vehicle( "car" ); console.log( secondInstance ); // vehicle: car, model:default, license: 00000-000
  • 12. BEHAVIOURAL DESIGN PATTERNS Behavioural design patterns focus on improving or streamlining through the identification of common communication patterns between various objects image credit: https://addyosmani.com/ resources/essentialjsdes ignpatterns/book/#categ oriesofdesignpatterns
  • 13. THE MEDIATOR PATTERNThis pattern usually implements a single object that becomes a shared resource through all of the different pieces of an application. ➤ Advantages ➤ Reduces the communication relationship from "many-to-many" to “many-to-one" ➤ Helps us pinpoint dependencies ➤ Excellent at decoupling objects which often promotes smaller, reusable components ➤ Disadvantages ➤ Introduces a single point of failure ➤ When modules communicate back and forth using a mediator pattern, it tends to become cumbersome and usually results in a clear performance hit var Mediator = ( function( window, undefined ) { function Mediator() { this._topics = {}; } Mediator.prototype.subscribe = function mediatorSubscribe( topic, callback ) { if( ! this._topics.hasOwnProperty( topic ) ) { this._topics[ topic ] = []; } this._topics[ topic ].push( callback ); return true; }; Mediator.prototype.unsubscribe = function mediatorUnsubscriBe( topic, callback ) { if( ! this._topics.hasOwnProperty( topic ) ) { return false; } for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) { if( this._topics[ topic ][ i ] === callback ) { this._topics[ topic ].splice( i, 1 ); return true; } } return false; }; Mediator.prototype.publish = function mediatorPublish() { var args = Array.prototype.slice.call( arguments ); var topic = args.shift(); if( ! this._topics.hasOwnProperty( topic ) ) { return false; } for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) { this._topics[ topic ][ i ].apply( undefined, args ); } return true; }; return Mediator; } )( window ); // example subscriber function var listener = function ExampleListener( myVariable ) { console.log( myVariable ); }; // example usages var myMediator = new Mediator(); myMediator.subscribe( 'some event', listener ); myMediator.publish( 'some event', 'foo bar' ); // console logs "foo bar"
  • 14. THE OBSERVER PATTERNThis pattern implements a single object (the subject) that maintains a reference to a collection of objects (known as "observers") and broadcasts notifications when a change to state occurs. ➤ Advantages ➤ Helps us pinpoint dependencies ➤ Excellent at decoupling objects which often promotes smaller, reusable components ➤ Disadvantages ➤ Checking the integrity of your application can become difficult ➤ Requires deeper-level thinking of the relationship between the various components of an application ➤ Switching a subscriber from one publisher to another can be costly // build the Subject base class var Subject = ( function( window, undefined ) { function Subject() { this._list = []; } // this method will handle adding observers to the internal list Subject.prototype.observe = function observeObject( obj ) { console.log( 'added new observer' ); this._list.push( obj ); }; Subject.prototype.unobserve = function unobserveObject( obj ) { for( var i = 0, len = this._list.length; i < len; i++ ) { if( this._list[ i ] === obj ) { this._list.splice( i, 1 ); console.log( 'removed existing observer' ); return true; } } return false; }; Subject.prototype.notify = function notifyObservers() { var args = Array.prototype.slice.call( arguments, 0 ); for( var i = 0, len = this._list.length; i < len; i++ ) { this._list[ i ].next.apply( null, args ); } }; return Subject; } )( window ); // setup an object that fetchs stocks function StockGrabber() { var subject = new Subject(); this.addObserver = function addObserver( newObserver ) { subject.observe( newObserver ); }; this.removeObserver = function removeObserver( deleteObserver ) { subject.unobserve( deleteObserver ); }; this.fetchStocks = function fetchStocks() { // fake fetching the stocks var stocks = { aapl : 167.00, goog : 243.67, msft : 99.34 }; // notify our observers of the stock change subject.notify( stocks ); }; }
  • 15. // define a couple of different observers var StockUpdaterComponent = { next : function() { console.log( '"next" called on StockUpdater with: ', arguments ); } }; var StockChartsComponent = { next : function() { console.log( '"next" called on StockCharts with: ', arguments ); } }; // example usage var stockApp = new StockGrabber(); stockApp.addObserver( StockUpdaterComponent ); stockApp.fetchStocks(); // console logs: "next" called on StockUpdater with... stockApp.addObserver( StockChartsComponent ); stockApp.fetchStocks(); // console logs: "next" called on StockUpdater with... "next" called on StockCarts with... stockApp.removeObserver( StockUpdaterComponent ); stockApp.fetchStocks(); // console logs: "next" called on StockCharts with... stockApp.removeObserver( StockChartsComponent ); stockApp.fetchStocks(); // does nothing; no observers THE OBSERVER PATTERNThis pattern implements a single object (the subject) that maintains a reference to a collection of objects (known as "observers") and broadcasts notifications when a change to state occurs. ➤ Advantages ➤ Helps us pinpoint dependencies ➤ Excellent at decoupling objects which often promotes smaller, reusable components ➤ Disadvantages ➤ Checking the integrity of your application can become difficult ➤ Requires deeper-level thinking of the relationship between the various components of an application ➤ Switching a subscriber from one publisher to another can be costly
  • 16. THE ITERATOR PATTERNProvide a way to access the elements of an aggregate object sequentially without exposing its underlying representation ➤ Advantages ➤ provides a standardised way to iterate any iterable object ➤ allows developers to design looping constructs that are far more flexible and sophisticated ➤ Disadvantages ➤ needs custom implementation ➤ hard to generate consistency do to lack of native JS implementation of Interfaces var Iterator = function(items) { this.index = 0; this.items = items; } Iterator.prototype = { first: function() { this.reset(); return this.next(); }, next: function() { return this.items[this.index++]; }, hasNext: function() { return this.index <= this.items.length; }, reset: function() { this.index = 0; }, each: function(callback) { for (var item = this.first(); this.hasNext(); item = this.next()) { callback(item); } } } // log helper var log = (function() { var log = ""; return { add: function(msg) { log += msg + "n"; }, show: function() { alert(log); log = ""; } } })(); function run() { var items = ["one", 2, "circle", true, "Applepie"]; var iter = new Iterator(items); // using for loop for (var item = iter.first(); iter.hasNext(); item = iter.next()) { log.add(item); } log.add(""); // using Iterator's each method iter.each(function(item) { log.add(item); }); log.show(); }
  • 17.
  • 19. BIG QUESTIONS ➤ What is Reactive Programming? ➤ A programming paradigm oriented around data flows and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow. ➤ Why should I consider adopting RP? ➤ It raises the level of abstraction of your code so you can focus on the interdependence of events that define the business logic, rather than having to constantly fiddle with a large amount of implementation details. Code in RP will likely be more concise ➤ What is a stream? ➤ Event buses or your typical click events are really an asynchronous event stream, on which you can observe and do some side effects. Reactive is that idea on steroids. You are able to create data streams of anything, not just from click and hover events. Streams are cheap and ubiquitous, anything can be a stream: variables, user inputs, properties, caches, data structures, etc. You can listen to that stream and react accordingly
  • 20. A HTTP REQUEST OBSERVABLE let requestStream = Rx.Observable.just('https://api.github.com/users'); let responseStream = requestStream .flatMap((requestUrl) => { return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl)); }); responseStream.subscribe((response) => { // render `response` to the DOM however you wish }); ➤ What are we doing? 1. we create a simple stream from a url string 2. we subscribe / observe that stream 3. we get every event on that stream ( requestUrl ) and make an http get request 4. then we “observe”(make a observable object) from the promise 5. pass that to the responseStream variable 6. observe(subscribe) to the result of the http call
  • 21. A DOM EVENT OBSERVABLE let domElement = document.querySelector('#someId'); let domElementObs = Rx.Observable.fromEvent(domElement, 'blur') .map((ev)=>ev.target.value); domElementObs.subscribe(ev => { console.log(ev); }); ➤ What are we doing? 1. we are creating an observable stream from the dom element’s “blur” event 2. we map / transform that event data so that we only get the input’s value 3. we subscribe / observe to the event stream and process the data.
  • 22. FLATMAP IS YOUR BEST FRIEND let source = Rx.Observable.interval(100).take(10) .flatMap( (res) => { return Rx.Observable.timer(500).map(()=>res*2) } ); source.subscribe(x=>console.log(x)); ➤ Why? 1. It transforms multiple streams of observables into a single observable 2. It does that by applying a rule defined by you 3. It helps you keep things clean and easy to understand
  • 23. A TYPEAHEAD SEARCH BOX function main() { var $input = $('#textInput'), $results = $('#results'); var keyup = Rx.Observable.fromEvent($input, 'keyup') .map(function (e) { return e.target.value; }) .filter(function (text) { return text.length > 2; }) .debounce(750) .distinctUntilChanged(); var searcher = keyup.flatMapLatest(searchWikipedia); searcher.subscribe( function (data) { $results .empty() .append($.map(data[1], function (v) { return $('<li>').text(v); })); }, function (error) { $results .empty() .append($('<li>')) .text('Error:' + error); }); } ➤ What are we doing? 1. we are creating an observable stream from the dom element’s “keyup” event 2. we filter that event data so that we only get values longer than 2 keys 3. we pause for 0.75 s 4. and do all this only if the value has changed 5. use flatMap to pass the input to the http method 6. subscribe to the stream and output the result to the dom
  • 24. OBSERVABLE AND/OR OPERATIONS // Get elements let weightSliderElem = document.querySelector('#weight-slider'); let weightTextElem = document.querySelector('#weight-text'); let heightSliderElem = document.querySelector('#height-slider'); let heightEditTextElem = document.querySelector('#height-edit-text'); let heightTextElem = document.querySelector('#height-text'); let bmiTextElem = document.querySelector('#bmi-text'); // Observables let weight = Rx.Observable.fromEvent(weightSliderElem, 'input') .map(ev => ev.target.value) .startWith(weightSliderElem.value); let height1 = Rx.Observable.fromEvent(heightSliderElem, 'input') .map(ev => ev.target.value) .startWith(heightSliderElem.value); let height2 = Rx.Observable.fromEvent(heightEditTextElem, 'input') .map(ev => parseInt(ev.target.value)) .startWith(heightEditTextElem.value); let height = height1.merge(height2); let bmi = weight.combineLatest(height, (w,h) => w/(h*h*0.0001)); // Subscriptions weight.subscribe(x => weightTextElem.innerHTML = x); height1.subscribe(x => heightTextElem.innerHTML = x); bmi.subscribe(x => bmiTextElem.innerHTML = x); ➤ What are we doing? 1. We start by creating observable streams from dom events 2. We create the height variable by combining multiple observable streams into a new observable 3. We create a new observable variable by using comblineLatest() method that emits a value ,filtered from the source observables latest emitted values. 4. We then handle the display logic. Code sample from André Staltz
  • 25. FURTHER READING AND DOCUMENTATION SOURCES➤ Best intro to RxJS in the world: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 ➤ The documentation: http://reactivex.io/documentation/observable.html ➤ Github page: https://github.com/Reactive-Extensions/RxJS ➤ egghead.io: https://egghead.io/technologies/rx ➤ And … google it

Notes de l'éditeur

  1. http://jsbin.com/puwagen/edit?html,js,console,output
  2. http://jsbin.com/sonoce/1/edit?html,js,output
  3. http://jsbin.com/hugusu/edit?js,output