cf.Objective() 2017 - Design patterns - Brad Wood

71
Design Patterns COMMON SOLUTIONS TO COMMON PROBLEMS Brad Wood @bdw429s Ortus Solutions

Transcript of cf.Objective() 2017 - Design patterns - Brad Wood

Page 1: cf.Objective() 2017 - Design patterns - Brad Wood

Design PatternsCOMMON SOLUTIONS TO COMMON PROBLEMS

Brad Wood@bdw429s

Ortus Solutions

Page 2: cf.Objective() 2017 - Design patterns - Brad Wood

Me

● Work for Ortus Solutions● Developer Advocate● Love rewriting Node code in CFML● Lead developer of CommandBox CLI● Live in Kansas City● Musician● 3 Ridiculously cute daughters● Like eating spicy foods

Page 3: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns

Page 4: cf.Objective() 2017 - Design patterns - Brad Wood

Software Craftsmanship

Page 5: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns

Christopher Alexander, architect

Born in Vienna in the 30’s

Page 6: cf.Objective() 2017 - Design patterns - Brad Wood

Architectural Design Patterns

Page 7: cf.Objective() 2017 - Design patterns - Brad Wood

A Pattern Language

1977 book on architecture, urban design, and community livability

The book creates a new language, what the authors call a pattern language derived from timeless entities called patterns.

Patterns describe a problem and then offer a solution. (253 patterns)

Page 8: cf.Objective() 2017 - Design patterns - Brad Wood

What is a Pattern?

“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”

Christopher Alexander

Page 9: cf.Objective() 2017 - Design patterns - Brad Wood

A Pattern Language

37 HOUSE CLUSTER

76 HOUSE FOR A SMALL FAMILY

159 LIGHT ON TWO SIDES OF EVERY ROOM

Page 10: cf.Objective() 2017 - Design patterns - Brad Wood

Gang of Four (GoF)

Page 11: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns:Elements of Reusable Object-Oriented Software

Inspired by Christopher’s work

23 programming patterns

Written by the “Gang of Four” in 1994

● Erich Gamma● Richard Helm● Ralph Johnson● John Vlissides

Page 12: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns:Elements of Reusable Object-Oriented Software

Creational Patterns

● Abstract Factory● Prototype● Singleton

Page 13: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns:Elements of Reusable Object-Oriented Software

Structural Patterns

● Composite● Decorator● Facade

Page 14: cf.Objective() 2017 - Design patterns - Brad Wood

Design Patterns:Elements of Reusable Object-Oriented Software

Behavioural Patterns

● Chain of Responsibility● Iterator● Strategy

Page 15: cf.Objective() 2017 - Design patterns - Brad Wood

Inspiration, not copy/paste examples

“The examples are there for inspiration and explanation of the ideas in the patterns. They aren't canned solutions; in all cases you'll need to do a fair bit of work to fit them into your application.”

Martin Fowler

Page 16: cf.Objective() 2017 - Design patterns - Brad Wood

Let’s look at some examples

Page 17: cf.Objective() 2017 - Design patterns - Brad Wood

Object Factory

https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)

Page 18: cf.Objective() 2017 - Design patterns - Brad Wood

Object Factory

● An object that creates other objects● Abstracts details of how the final objects are created● Removes creation code from inside object to separate concerns● Often used with the dependency injection pattern● CFML Examples are WireBox or DI/1

Page 19: cf.Objective() 2017 - Design patterns - Brad Wood

Singleton

https://sourcemaking.com/design_patterns/singleton

Page 20: cf.Objective() 2017 - Design patterns - Brad Wood

Singleton

● Ensure class only has one instance● Provide global access to this instance● Just-in-time initialization● Often times doesn’t hold state● Object must be thread safe!

Page 21: cf.Objective() 2017 - Design patterns - Brad Wood

Singleton

function onApplicationStart() {

application.myService = new models.myService();

}

Page 22: cf.Objective() 2017 - Design patterns - Brad Wood

Strategy

https://sourcemaking.com/design_patterns/strategy

Page 23: cf.Objective() 2017 - Design patterns - Brad Wood

Strategy

● Define a family of algorithms● Each one is encapsulated and interchangeable● Often times each strategy implements an interface● Each implementation can be different● Strategies can be chosen at runtime● Strategy in use is invisible to the program

Page 24: cf.Objective() 2017 - Design patterns - Brad Wood

Strategy

logger.setAppender( new fileAppender() );

logger.logMessage( ‘This is my message’ );

logger.setAppender( new dbAppender() );

logger.logMessage( ‘This is my message’ );

Page 25: cf.Objective() 2017 - Design patterns - Brad Wood

Decorator

https://sourcemaking.com/design_patterns/decorator

Page 26: cf.Objective() 2017 - Design patterns - Brad Wood

Decorator

● Add responsibilities to a class dynamically● Alternative to subclassing (not really an “is-a”)● Decorator wraps original class● Wrapping can be recursive● Can be applied at runtime● User of class does not know (or care) if it’s been decorated

Page 27: cf.Objective() 2017 - Design patterns - Brad Wood

iceCream = new iceCream();

iceCream.make();

sprinkledIceCream = new sprinklesDecorator( iceCream );

sprinkledIceCream.make();

Decorator

Page 28: cf.Objective() 2017 - Design patterns - Brad Wood

Adapter

https://sourcemaking.com/design_patterns/adapter

Page 29: cf.Objective() 2017 - Design patterns - Brad Wood

Adapter

● Modify the API of a class to be different● Can “adapt” a class to work in another system● Wraps the original class with a new interface● Allows greater reuse● Doesn’t modify original class

Page 30: cf.Objective() 2017 - Design patterns - Brad Wood

Adapter

oldCache = new oldCacheEngine();

oldCache.retrieve( ‘item’ );

adaptedCache = new cacheAdapter( oldCache );

adaptedCache.get( ‘item’ );

Page 31: cf.Objective() 2017 - Design patterns - Brad Wood

Front Controller

https://en.wikipedia.org/wiki/Front_controller

Page 32: cf.Objective() 2017 - Design patterns - Brad Wood

Front Controller

● A single point of entry for a web app● Simplifies URL routing● Makes global concerns like security checks easier● Utilizes a controller to dispatch to the appropriate handler● Usually index.cfm in CFML apps

Page 33: cf.Objective() 2017 - Design patterns - Brad Wood

Front Controller

yoursite.com/index.cfm?event=main.index

Page 34: cf.Objective() 2017 - Design patterns - Brad Wood

Chain of Responsibility

https://sourcemaking.com/design_patterns/chain_of_responsibility

Page 35: cf.Objective() 2017 - Design patterns - Brad Wood

Chain of Responsibility

● You have a large or dynamic list of handlers that need to respond to a request

● You don’t want to couple the sender to the responders● Creates a pipeline of linked handlers● Each handler calls the next link in the chain● A handler can abort the chain by not calling the next handler

Page 36: cf.Objective() 2017 - Design patterns - Brad Wood

Chain of Responsibility

function securityHandler( request ) {

if( !request.params.authenticated ){

throw ‘Not logged in’!

}

// Pass control to the next link in the chain

request.proceed();

}

Page 37: cf.Objective() 2017 - Design patterns - Brad Wood

Memento

https://sourcemaking.com/design_patterns/memento

Page 38: cf.Objective() 2017 - Design patterns - Brad Wood

Memento

● Capture and externalize an object's internal state● Can be used to “snapshot” an object● Can be used to restore an object to a previous state● Great for serialization● Can include composed objects

Page 39: cf.Objective() 2017 - Design patterns - Brad Wood

Memento

oUser = userService.loadUser( id=123 );

currentUserState = oUser.getMemento();

Page 40: cf.Objective() 2017 - Design patterns - Brad Wood

Observer(publish/subscribe)

https://sourcemaking.com/design_patterns/observer

Page 41: cf.Objective() 2017 - Design patterns - Brad Wood

Observer (publish/subscribe)

● Defines “events” that are broadcast ● Defines zero or more observers who are listening to those events● Promotes decoupling of a large system● Listener can receive data about the event that has happened● Bind listeners at runtime for dynamic behaviors● Don’t call us, we’ll call you!

Page 42: cf.Objective() 2017 - Design patterns - Brad Wood

Observer (publish/subscribe)

$.ajax({

url: "test.html",

context: document.body

}).done(function() {

$( this ).addClass( "done" );

});

Page 43: cf.Objective() 2017 - Design patterns - Brad Wood

Double Checked Locking

https://en.wikipedia.org/wiki/Double-checked_locking

Page 44: cf.Objective() 2017 - Design patterns - Brad Wood

Double Checked Locking

● Protects creation of a shared resource with multithreading● Reduces overhead of acquiring exclusive locks by first performing

a read-only check● If creation is required, only then is an exclusive lock acquired● Once a thread has the exclusive lock, the check is performed a

second time to ensure another thread hasn’t completed it● Ensures thread safety without excessive locking

Page 45: cf.Objective() 2017 - Design patterns - Brad Wood

Double Checked Locking

if( isDefined( 'data' ) ){ return data; }

lock name="generateData" type="exclusive" timeout=60 {

if( isDefined( 'data' ) ){ return data; }

data = produceData();

return data;

}

Page 46: cf.Objective() 2017 - Design patterns - Brad Wood

Anti-patterns(Avoid these!)

Page 47: cf.Objective() 2017 - Design patterns - Brad Wood

Anemic Domain Model

https://en.wikipedia.org/wiki/Anemic_domain_model

Page 48: cf.Objective() 2017 - Design patterns - Brad Wood

Anemic Domain Model

● When domain model is too “thin” and lacks any behavior● Beans are only value objects with no behavior present● Services are empty, meaning business logic has probably ended

up in your controllers or views● Creates excessive classes● Bloats application code

Page 49: cf.Objective() 2017 - Design patterns - Brad Wood

Anemic Domain Model

component accessors=true {

property name=’name’;

property name=’age’;

property name=’department’;

}

Page 50: cf.Objective() 2017 - Design patterns - Brad Wood

God Object

https://sourcemaking.com/antipatterns/the-blob

Page 51: cf.Objective() 2017 - Design patterns - Brad Wood

God Object

● A class with too much responsibility● API is watered down with many unrelated methods● Usually happens over time as code is added and never refactored● Hard to maintain and test● Lazy domain design and lack of planning

Page 52: cf.Objective() 2017 - Design patterns - Brad Wood

God Object

util = new generalControllerUtil();

util.createOrder();

util.addUser();

util.login();

util.runScheduledTasks();

util.orderPizza();

Page 53: cf.Objective() 2017 - Design patterns - Brad Wood

Premature Optimization

https://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/

Page 54: cf.Objective() 2017 - Design patterns - Brad Wood

Premature Optimization

● Coding early-on for perceived efficiency● Sacrificing good design, maintainability● Often times overstating a negligible speed improvement● Sometimes “proven” by a flawed “loop test”● The “root of all evil” -- Donald Knuth

Page 55: cf.Objective() 2017 - Design patterns - Brad Wood

Improbability Factor

https://en.wikipedia.org/wiki/Improbability_factor

Page 56: cf.Objective() 2017 - Design patterns - Brad Wood

Improbability Factor

● Leaving known bugs in your system because they’re “not likely to happen”

● Gambling with fate to save time and be lazy● This is just inviting Murphy’s Law to come into full effect● Can bite you later at the worst possible time

Page 57: cf.Objective() 2017 - Design patterns - Brad Wood

Improbability Factor

reportService.runAsyncReport();

// Meh, this should be enough

sleep( 5000 );

fileRead( ‘/reports/sales.pdf’ );

Page 58: cf.Objective() 2017 - Design patterns - Brad Wood

Honorable Mentions

Page 59: cf.Objective() 2017 - Design patterns - Brad Wood

Law of Demeter

https://en.wikipedia.org/wiki/Law_of_Demeter

Page 60: cf.Objective() 2017 - Design patterns - Brad Wood

Law of Demeter

● Principle of least knowledge● A unit of software should have limited knowledge about the other

units● Software units should talk to friends and not to strangers● Keeps low coupling between systems● Rule of thumb: be careful accessing methods on objects obtained

from other objects (the “dot” rule)

Page 61: cf.Objective() 2017 - Design patterns - Brad Wood

Law of Demeter

orderCity = cart

.getOrder()

.getOrderDetails()

.getUser()

.getAddress()

.getCity()

.getName();

Page 62: cf.Objective() 2017 - Design patterns - Brad Wood

Principle of Least Astonishment

https://en.wikipedia.org/wiki/Principle_of_least_astonishment

Page 63: cf.Objective() 2017 - Design patterns - Brad Wood

Principle of Least Astonishment (POLA)

● Applies to UI and software design● "If a necessary feature has a high astonishment factor, it may be

necessary to redesign the feature”● User controls should have a consistent behavior● Predictable software is easier to use● Basically, don’t make your users go “WTF!?”

Page 64: cf.Objective() 2017 - Design patterns - Brad Wood

Principle of Least Astonishment (POLA)

// Has side effect of removing all login history

user.getAPIKey();

Page 65: cf.Objective() 2017 - Design patterns - Brad Wood

Brook’s Law

https://en.wikipedia.org/wiki/Brooks%27s_law

Page 66: cf.Objective() 2017 - Design patterns - Brad Wood

Brook’s Law

● “Adding manpower to a late software project makes it later"● Coined by Fred Brooks in his 1975 book The Mythical Man-Month● Software development is knowledge work, and not fungible ● Throwing devs at a project will slow it down at first● A larger team has more points of contact● If 1 woman can have a baby in 9 months, it doesn’t mean 9

women can have a baby in 1 month

Page 67: cf.Objective() 2017 - Design patterns - Brad Wood

Resources

Page 68: cf.Objective() 2017 - Design patterns - Brad Wood

Head First Design Patterns: A Brain-Friendly Guide

Page 69: cf.Objective() 2017 - Design patterns - Brad Wood

Software Architecture Design Patterns in Java

Page 70: cf.Objective() 2017 - Design patterns - Brad Wood

https://sourcemaking.com/design_patterns

Page 71: cf.Objective() 2017 - Design patterns - Brad Wood

Thanks for coming!

Contact me

[email protected]● www.codersrevolution.com● @bdw429s● Ortus Solutions