cf.Objective() 2017 - Design patterns - Brad Wood
-
Upload
ortus-solutions-corp -
Category
Software
-
view
510 -
download
2
Transcript of cf.Objective() 2017 - Design patterns - Brad Wood
Design PatternsCOMMON SOLUTIONS TO COMMON PROBLEMS
Brad Wood@bdw429s
Ortus Solutions
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
Design Patterns
Software Craftsmanship
Design Patterns
Christopher Alexander, architect
Born in Vienna in the 30’s
Architectural Design Patterns
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)
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
A Pattern Language
37 HOUSE CLUSTER
76 HOUSE FOR A SMALL FAMILY
159 LIGHT ON TWO SIDES OF EVERY ROOM
Gang of Four (GoF)
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
Design Patterns:Elements of Reusable Object-Oriented Software
Creational Patterns
● Abstract Factory● Prototype● Singleton
Design Patterns:Elements of Reusable Object-Oriented Software
Structural Patterns
● Composite● Decorator● Facade
Design Patterns:Elements of Reusable Object-Oriented Software
Behavioural Patterns
● Chain of Responsibility● Iterator● Strategy
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
Let’s look at some examples
Object Factory
https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)
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
Singleton
https://sourcemaking.com/design_patterns/singleton
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!
Singleton
function onApplicationStart() {
application.myService = new models.myService();
}
Strategy
https://sourcemaking.com/design_patterns/strategy
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
Strategy
logger.setAppender( new fileAppender() );
logger.logMessage( ‘This is my message’ );
logger.setAppender( new dbAppender() );
logger.logMessage( ‘This is my message’ );
Decorator
https://sourcemaking.com/design_patterns/decorator
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
iceCream = new iceCream();
iceCream.make();
sprinkledIceCream = new sprinklesDecorator( iceCream );
sprinkledIceCream.make();
Decorator
Adapter
https://sourcemaking.com/design_patterns/adapter
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
Adapter
oldCache = new oldCacheEngine();
oldCache.retrieve( ‘item’ );
adaptedCache = new cacheAdapter( oldCache );
adaptedCache.get( ‘item’ );
Front Controller
https://en.wikipedia.org/wiki/Front_controller
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
Front Controller
yoursite.com/index.cfm?event=main.index
Chain of Responsibility
https://sourcemaking.com/design_patterns/chain_of_responsibility
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
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();
}
Memento
https://sourcemaking.com/design_patterns/memento
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
Memento
oUser = userService.loadUser( id=123 );
currentUserState = oUser.getMemento();
Observer(publish/subscribe)
https://sourcemaking.com/design_patterns/observer
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!
Observer (publish/subscribe)
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$( this ).addClass( "done" );
});
Double Checked Locking
https://en.wikipedia.org/wiki/Double-checked_locking
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
Double Checked Locking
if( isDefined( 'data' ) ){ return data; }
lock name="generateData" type="exclusive" timeout=60 {
if( isDefined( 'data' ) ){ return data; }
data = produceData();
return data;
}
Anti-patterns(Avoid these!)
Anemic Domain Model
https://en.wikipedia.org/wiki/Anemic_domain_model
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
Anemic Domain Model
component accessors=true {
property name=’name’;
property name=’age’;
property name=’department’;
}
God Object
https://sourcemaking.com/antipatterns/the-blob
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
God Object
util = new generalControllerUtil();
util.createOrder();
util.addUser();
util.login();
util.runScheduledTasks();
util.orderPizza();
Premature Optimization
https://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/
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
Improbability Factor
https://en.wikipedia.org/wiki/Improbability_factor
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
Improbability Factor
reportService.runAsyncReport();
// Meh, this should be enough
sleep( 5000 );
fileRead( ‘/reports/sales.pdf’ );
Honorable Mentions
Law of Demeter
https://en.wikipedia.org/wiki/Law_of_Demeter
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)
Law of Demeter
orderCity = cart
.getOrder()
.getOrderDetails()
.getUser()
.getAddress()
.getCity()
.getName();
Principle of Least Astonishment
https://en.wikipedia.org/wiki/Principle_of_least_astonishment
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!?”
Principle of Least Astonishment (POLA)
// Has side effect of removing all login history
user.getAPIKey();
Brook’s Law
https://en.wikipedia.org/wiki/Brooks%27s_law
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
Resources
Head First Design Patterns: A Brain-Friendly Guide
Software Architecture Design Patterns in Java
https://sourcemaking.com/design_patterns
Thanks for coming!
Contact me
● [email protected]● www.codersrevolution.com● @bdw429s● Ortus Solutions