Sunday 11 January 2015

JavaScript Design Patterns (Composite, Façade, Adapter)

JavaScript Design Patterns


 Composite Design Pattern 
  • Dfn: 
    • Dynamic User Interfaces achieved by replacing Groups of Objects with a Single Object organised in a Tree Hierarchical Structure in order to leverage functionality such that a Single Command (Function Call) on a Composite Object (Top-Level Parent) that will traverse an entire Nested tree of Collection(s) (composition) of many Sub-Objects and initiate Delegation with the same implementation method / Operation (Complex Behaviour) Recursively to its now independent Loosely Coupled bottom-level Leaf Objects (Leaves do not have Children) whose implementation may be hidden from clients, which provides choice and flexibility in selection of preferred Data Structures used to hold the Children, which may include Arrays, Objects, etc. All Objects within a Composite (including Leaves) must implement and respond to the same Composite Interfaces var ___ = new Interface(___); that must be defined for each Object Class (perhaps using a UML Diagram, accompanied by Duck Typing using Interface , or Type Checking), but Children are not Subclasses and do not Inherit from the Composite. 
  • Application Examples: 
    • Dynamic Input Form with Operations Saving, Restoring, Resetting, Validation, AJAX requests
    • Dynamic Media Gallery with Operations Drag-and-Drop, Hiding, Showing 
  • Usage Approach:
    • Super (Composite) View that has Children (has one or many) that are initially Unknown (Contents and Quantity) Partial (Leaf) Views that may be Grouped into Sets (Composite) of Partials and are potentially Different for each User and Dependent on User Interaction leverages Loosely Coupling:
      • Operations of Inputs is performed Dynamically on the Composite Design Pattern Framework with a Single Command that is called Recursively on all the Composites bottom-level Leaves / Children (not Tightly Coupled to specific input fields) by means of wrapping HTML elements inside JavaScript Objects
      • Additionally Operations and Levels in the Hierarchy may be added to the Modular Composite Interface of the Composite Design Pattern Framework to achieve higher Granularity on Operations that may be called (without affecting existing Object Classes)
  • Benefits: 
    • Loosely Coupled
    • Modular
    • Maintainable
    • Reuse (DRY)
    • Refactorable
  • Warnings: 
    • Cookies should not be used as a Data Structure to Store User Data and Children (Data Validity easily hacked, length restrictions may strip and cause missing data, contained in HTTP Headers of all requests causing performance lag)
    • DOM Nodes should not be used as a Data Structure to Store Children elements to avoid Memory Leaks in browsers caused by necessity for them to maintain reference to their JS wrapper class to implement operations. Use an Array instead.
    • Documentation must highlight the Restrictions that elements cause to the Composite's usefulness, and the Performance Cost each Operation supports, since in large hierarchies the call will still initiate complete traversal to all children in a tree.


 Façade Design Pattern 
  • Dfn: 
    • Organising Pattern that Decouples (Loose Coupling) and conveniently Wraps an Object, changing the Interface it presents to the world by simplifying it and making assumptions (rather than providing extra options like the Adapter Design Pattern) to simplify common and repetitive tasks involved in the process of accessing and modifying complex Classes (contained in an App) and Objects from the Client code (that calls it) in order to save time and maintain Efficiency to meet Demands
    • Utility Libraries
      • Convenience Methods created to increase Flexibility (combining methods) whilst maintaining Granularity (also separately retaining the individual methods that have been combined for convenience) along with ease of interacting (user-friendly presentation of an Object's features) with complex subsystems indirectly, with less likelihood of errors found directly (error checking performed behind the scenes), by combining several existing methods into one
  • Application Examples
    • Shortcut Icons (acts as Facade Interface) navigate deeply nested files and directories
    • Operations on OS GUI (acts as Facade Interface) that indirectly runs commands in background to computer data and functionality 
    • Adding an Event Function (Convenient Methods encapsulates detection code in single location acting as Facade Interface) allows Event Listeners to be added to DOM nodes, by performing cross-browser determination and branching code to detect capabilities and differences between browsers (using Object Detection and Browser Sniffing techniques using Lazy Loading at load time by Abstraction and execution once instead of on every call to speed up the app) with the heavy lifting performed under the hood for implementation of appropriate event listener syntax or event attachment technique to use (reuse hidden low-level code to check against browser differences to avoid repeated manually checking)
    • Abstract cross-browser differences into a Custom Event Utility with Facade Methods that provide a consistent Interface (act as a Facade Interface) to work comfortably (or alternatively with Third-Party Libraries such as Prototype, jQuery, YUI), easily interacting with JS functions built into each Browsers and deal with cross-browser event handling by Batching Utilities into Single Set, and using a Singleton Design Pattern containing Static Methods within a Namespace (Common Methods i.e. getMail, sendMail, archive, or alternatively using a Publish / Subscribe Design Pattern).
    • Wrapper Library or Shims (act as Facade Interface) to help Interface with a Collection of poorly designed APIs by Wrapping them in Single API (with good design)
    • Set Multiple Styles to Multiple HTML Elements' CSS Style Properties at same time by creating a Utility Function (acting as a Facade Interface using the Facade Pattern) to simplify matching HTML Elements and setting CSS Styles in Bulk, whereby we Batch all the HTML Elements and CSS Styles functionality together (under the hood without the client code being aware of the details or being broken by modifications) and trigger it all with just a Single Function Call
    • Error Logging
    • Tracking Page View Stats
  • Benefits: 
    • Loosely Coupled
    • Maintainable
    • Understandable
    • Reuse (DRY)
    • Abstract-Oriented
  • Warnings: 
    • Practicality of Operations must be considered to avoid unnecessary drag by Expensive routines (i.e. a simple task may only need a few simple Facade Functions rather than an entire JS Library)
    • Multiple Constituent Functions may be preferable to a Single Monolithic Facade Function to achieve desired Granularity

 Adapter Design Pattern 
  • Dfn: 
    • Decouples (Loose Coupling) of a Wrapper Object (of the Adapter Design Pattern) Abstraction from its Implementation (enabling independent variation), by using a thin layer of code between incompatible method calls is used to encapsulate an existing Interface that has otherwise Incompatible Classes (which prevents clients from accessing the API) with another different Interface by Migrating and adapting them by reconciling differences in syntax and allowing them to interact together through conversion to bridge differences and achieve Compatibility (it is different from the Facades Design Pattern, as it doesn't remove abilities or simplify the Interface for Convenience sake)
  • Application Examples
    • Interfaces of designed Classes may be Incompatible with Existing APIs. Adapter Design Pattern may be used to allow interaction with the API from these Classes without modifying them directly (and possible breaking them)
    • Existing API Interfaces may change, requiring all client code to be updated to be Compatible with the New Interface. Development of a Client Adapter that implements the New Interface is necessary to survive
    • Adapting between two Libraries by creating two Adaptor Methods to convert the difference between their Interfaces
    • Adapters to create Different Interfaces easier for clients to use
    • Adapter created to access a New API (different Interfaces) instead of an Expensive entire Codebase Rewrite, by Wrapping and handling the logic within a New Interface for an Existing Class without breaking existing implementations
  • Warnings: 
    • Considerations when choosing Set of Utilities for a Library include
      • Impact Determination (Development Suitability)
        • Match with Coding Style of Developers
        • Ease of Implementation
        • Incompatibility with Existing Codebase
      • Interchangeability with Alternative Libraries (Decoupled without requiring changes to Codebase) to improve Performance, Security, Design
      • Compatibility with Intermediary Sets of Adapters during migration from Existing API to New API
      • Expense of an Entire Code Rewrite VS New Adapter Library
    • Consideration when determining between Entire Code (API / Library) Rewrite VS New Adapter Library
      • Extent that Existing API / Library is Standardised
        • Avoid unnecessary development overhead (new set of Utilities that must be supported) of an Adapter when the Existing (Legacy) API or the New Interface proposed to be made compatible are incomplete

References:
  • Chapters 9 - 11, Pro JavaScript Design Patterns by Ross Harmes and Dustin Diaz
Note: Refer to similarities between these JavaScript Design Patterns and the iOS Design Patterns highlighted in one of my previous blog posts

Books
  • 60% Progress Pro JavaScript Design Patterns



No comments:

Post a Comment