óCoffeeScript Cookbook

Bridge Pattern

Problem

You need to maintain a reliable interface for code that can change frequently or change between multiple implementations.

Solution

Use the Bridge pattern as an intermediate between the different implementations and the rest of the code.

Assume that you developed an in-browser text editor that saves to the cloud. Now, however, you need to port it to a stand-alone client that saves locally.

class TextSaver
    constructor: (@filename, @options) ->
    save: (data) ->

class CloudSaver extends TextSaver
    constructor: (@filename, @options) ->
        super @filename, @options
    save: (data) ->
        # Assuming jQuery
        # Note the fat arrows
        $( =>
            $.post "#{@options.url}/#{@filename}", data, =>
                alert "Saved '#{data}' to #{@filename} at #{@options.url}."
        )

class FileSaver extends TextSaver
    constructor: (@filename, @options) ->
        super @filename, @options
        @fs = require 'fs'
    save: (data) ->
        @fs.writeFile @filename, data, (err) => # Note the fat arrow
            if err? then console.log err
            else console.log "Saved '#{data}' to #{@filename} in #{@options.directory}."

filename = "temp.txt"
data = "Example data"

saver = if window?
    new CloudSaver filename, url: 'http://localhost' # => Saved "Example data" to temp.txt at http://localhost
else if root?
    new FileSaver filename, directory: './' # => Saved "Example data" to temp.txt in ./

saver.save data

Discussion

The Bridge pattern helps you to move the implementation-specific code out of sight so that you can focus on your program's specific code. In the above example, the rest of your application can call saver.save data without regard for where the file ultimately ends up.