Web-First Design Patterns

Preview:

DESCRIPTION

 

Citation preview

Michael Mahemoff @mahemoff +mahemoff

Web-FirstDesign

Patterns

Be Very Afraid

Evolution of Design Patterns

The Mother of All Design Principles

Web-First Patterns

The Mother of All Design Patterns

Pattern-Fu

Static Websites

Interactive Websites

Single Page Apps

ModularityPrinciple

Tight Coupling

Tight Coupling

#highCohesion #lowCoupling

#modularity #isolation #separationOfConcerns

#widget #webComponent#domainObject #module

A runtime configuration

Mediator

Good: No more coupling

Good: No more coupling

Good: Reuse elsewhere

TestDriver

Good: We can test!

SemanticEventsPattern

eventA eventB eventC

eventA eventB eventC

shopcart

itemadded

item removed

itemchanged

#observer #listener #events #pubsub #mvc #messaging

Web-First

Automagic Event

Registration

The Problem: Event Registration

eventA eventB eventC

Timer = {

init: function() { listen(“pageLoad”, this.onPageLoad); listen(“trialStart”, this.onTrialStart); listen(“trialEnd”, this.onTrialEnd); }

}

The Problem: Event Registration

Timer = { pageLoad: function() { … } trialStart: function() { … } trialEnd: function() { … }}

Solution: Automagic Registration

AppMediator = {

init: function() {

var components=[Trial, Counter, …] var handlers = { init: [], trialStart: [], trialEnd: [] }

for (eventType in handlers) { components.forEach(function(component) { if (component[eventType]) handlers[eventType].push(component); } }

}

fire: function(eventType) { … }

}

Solution: Automagic Registration

Timer = { pageLoad: function() { … } onTrialStart: function() { … } onTrialEnd: function() { … }}

Timer = { pageLoad: function() { … } onTrialStart: function() { … } onTrialEnd: function() { … }}

An example ofConvention Over Configuration

OOCSSS

credit: Nicole Sullivan

h1 { background: blue; font-family: arial;}

#account h1 { background: red;}

#account h1:hover { border-color: black;}

The Problem:CSS Jungle

.account { background: #f9a;}

.heading { color: #882;}

Solution:Use classes, not IDs or Tags

.account { background: #f9a;}

.heading { color: #882;}

Solution:Avoid hierarchies

ClassyHTML

The Problem:Complex Display Logic

Logged in?Show name

Allowed to rate?Show thumbs

Leaving a comment?Show textarea

Managing your page?Show edit controls

function startEditing() { $(‘.titleInput’).show(); $(‘.mixPanel’).slideDown(); $(‘.comments’).fadeOut();}

function stopEditing() { $(‘.titleInput’).hide(); $(‘.mixPanel’).slideUp(); $(‘.comments’).fadeIn();}

The Problem:Complex Display Logic

$('html’).addClass(‘editing’);$('html’).removeClass(‘editing’);

Solution: Root-level class

.mixPanel { display: none;}

.editing .mixPanel { display: block;}

$('html’).addClass(‘editing’);$('html’).removeClass(‘editing’);

Solution: Root-level class

.comments { height: 0; position: absolute; transition: all 0.5s linear;}

.editing .comments { height: 4em;}

<div class=‘mixPanel forEditing’> ...</div>

Generalising It

.forEditing { display: none;}

.editing .forEditing { display: block;}

LiveTemplate

a speculative pattern

<! accounts.forEach(account) { > <li><!= account.balance ></li><! } >

The Problem:Even client-side templates are static

<ul> <li>28.50</li> <li>48.50</li> <li>78.12</li></ul>

The Problem:Can’t transform representation

<tr> <td>28.50</td> <td>48.50</td> <td>78.12</td></tr>

Solution:Track the template

<ul class=‘accountTemplate’> <li>28.50</li> <li>48.50</li> <li>78.12</li></ul>

Solution:Or wait for <template> tag!

<ul class=‘accountTemplate’> <li>28.50</li> <li>48.50</li> <li>78.12</li></ul>

METATIPS:Pattern-Fu

A little chaos is okay(the world won’t end)

Agile+Lean: Technical Debt

Order out of chaos

Shuhari:Obey, Detach, Leave

ThankyouMichael Mahemoff

@mahemoff+mahemoff

Recommended