GoF Structural patterns

Definition

Structural Design Patterns are concerned with object composition and typically identify simple ways to realize relationships between different objects. They help ensure that when one part of a system changes, the entire structure of the system doesn't need to do the same. They also assist in recasting parts of the system which don't fit a particular purpose into those that do.

  • Adapter

  • Bridge

  • Composite

  • Decorator

  • Facade

  • Flyweight

  • Proxy

Adapter

Adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.

Example:

class Soldier {
  constructor(level) {
    this.level = level;
  }
  attack() {
    return this.level * 1;
  }
}

class Jedi {
  constructor(level) {
    this.level = level;
  }
  attackWithSaber() {
    return this.level * 100;
  }
}

class JediAdapter {
  constructor(jedi) {
    this.jedi = jedi;
  }
  attack() {
    return this.jedi.attackWithSaber();
  }
}

Bridge

Bridge decouples an abstraction from its implementation so that the two can vary independently.

Example:

Composite

Composite composes zero-or-more similar objects so that they can be manipulated as one object.

Example:

Decorator

Decorator dynamically adds/overrides behavior in an existing method of an object.

Example:

Facade

Facade provides a simplified interface to a large body of code.

The Facade pattern is used when we want to show the higher level of abstraction and hide the complexity behind the large codebase. Think of it as simplifying the API being presented to other developers, something which almost always improves usability

Pros and Cons

Pros:

  • Reduces the learning curve necessary to successfully leverage the subsystem

  • Promotes decoupling the subsystem from its potentially many clients

Cons:

  • Facade is the only access point for the subsystem, it will limit the features and flexibility that "power users" may need

  • performance costs of having one more high-level abstraction

Facade vs Adapter

Facade defines a new interface, whereas Adapter uses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design an existing interface. While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.

Example:

Example in FE world: A great example of this pattern is used in the common DOM manipulation libraries like jQuery, which simplifies the selection and events adding mechanism of the elements.

Flyweight

Flyweight reduces the cost of creating and manipulating a large number of similar objects.

Example:

Proxy

Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

Example:

Last updated