Series catalog:

  • [1] — Creative design Patterns
  • JavaScript Design Pattern Parsing [2] — Structural design Pattern
  • JavaScript Design Pattern Parsing [3] — Behavioral design Patterns
  • JavaScript Design Pattern parsing [4] — Decorator pattern, appearance pattern, mediator pattern

Adapter mode

The adapter pattern is primarily used to solve the problem of mismatches between two existing interfaces, regardless of how they were implemented or how they might evolve in the future. The adapter pattern allows them to work together without changing existing interfaces.

An adapter, also known as a wrapper, is an uncomplicated pattern, and there are many such scenarios in everyday development: For example, when we try to call a module or an object interface, only to find that the interface format is not up to the present needs, there are two solutions at this moment, the first we directly modifying the original interface implementations, but if the original modules, or object is complex, or we get is already has compressed code, Then it is unrealistic to modify the original interface. The second method is the adapter, which converts the original interface into the interface you want to get, and you just need to get it through the adapter, and you don’t need to modify the original module or object.

To take an abstract example, let’s say we have two computers that need to be charged:

class ThinkPad {
  charge() {
    console.log('ThinkPad starts charging ');
  }
}


class MacBook {
  charge() {
    console.log('MacBook starts charging ')}} // Power to chargefunction PowerToCharge(laptop) {
  if(laptop.charge instanceof Function) {laptop.charge()}} PowerToCharge(new ThinkPad()) // ThinkPad starts charging PowerToCharge(new MacBook()Copy the code

However, if the MacBook cannot be charged directly with a power interface, we may need an adapter, which is also used in the adapter mode. We cannot directly change the interface on the computer, but we can charge through a layer of adapter (encapsulation)

class ThinkPad {
  charge() {
    console.log('ThinkPad starts charging ');
  }
}


class MacBook {
  type_cCharge() {
    console.log('MacBook starts charging 'Class TypeCToDp {// Define an adapter class to connect to a MacBook.charge() {
    let macbook = new MacBook();
    returnMacbook.type_ccharge ()}} // Power chargefunction PowerToCharge(laptop) {
  if(laptop.charge instanceof Function) {laptop.charge()}} PowerToCharge(new ThinkPad()) // ThinkPad starts charging PowerToCharge(new TypeCToDp()) // MacBook starts chargingCopy the code

conclusion

  • The adapter pattern is a relatively simple one, but there are many scenarios that adapters use at the JS or BFF layer.
  • At the same time, however, it is important to realize that the adapter pattern is a remedy for some old unmaintainable or stable interface incompatibility problems, and should be reduced or not used at the beginning of development, but rather to plan for interface consistency.
  • The adapter does not change the original interface, but rather wraps one object around another.
  • The adapter pattern conforms to the open closed principle.

The proxy pattern

The proxy pattern provides a proxy or placeholder for an object to control access to it.

Proxy mode is a very interesting mode, we can find many proxy mode scenarios in our life. For example, the agent of a star will not directly contact the star in general business activities, but talk with the agent, the agent will negotiate the work content and remuneration before handing over to the star.

Simple implementation of the proxy pattern

Let’s use an example of a star buying a bag to explain the agency

Being a star doesn’t have an agent to buy her own bag

// Define a package class
class Bags {
  constructor(props) {
    this.name = props;
  }
  getName() {
    return this.name; }}// Define a star object
class Star {
  buyBag(bag) {
    console.log('Got one${bag.getName()}Package `); }}// Create a star instance
let star = new Star();
star.buyBag(new Bags('Coach')); // Get a Coach bag
Copy the code

When a star sends his assistant to buy a bag

// Define a package class
class Bags {
  constructor(props) {
    this.name = props;
  }
  getName() {
    return this.name; }}// Define an assistant object
class Assistant {
  constructor(props) {
    this.star = props;
  }
  buyBag(bag) {
    this.star.buyBag(bag); }}// Define a star object
class Star {
  buyBag(bag) {
    console.log('Got one${bag.getName()}Package `); }}// Create a star instance
let star = new Star();
let assistant = new Assistant(star);
assistant.buyBag(new Bags('Coach')); // Get a Coach bag
Copy the code

At this point, we have implemented a simple proxy pattern, but we would not normally use proxies in such a simple scenario, instead adding code complexity.

Proxy usage scenarios

Images of lazy loading is tend to use the proxy pattern in the front of the scene, when the network is bad, the loading of the images will take a period of time, it will produce gap, affect the user experience, at the pictures really finish loading before, this time using a loading to take pictures, such as image really finish loading in set the SRC attribute, to implement lazy loading the image.

class ABigImage {
  constructor() {
    this.img = new Image();
    document.body.appendChild(this.img);
  }
  setSrc(src) {
    this.img.src = src; }}class ProxyImage {
  constructor() {
    this.proxyImage = new Image();
  }

  setSrc(src) {
    let bigImageObj = new ABigImage();
    bigImageObj.img.src = './local.png'; // Low resolution image URL or local image
    this.proxyImage.src = src;
    this.proxyImage.onload = function() { bigImageObj.img.src = src; }}}var proxyImage = new ProxyImage();
proxyImage.setSrc('image Url')
Copy the code

We can see this in the demo (enabling the Disable cache in Chrome’s Network and setting the speed to slow 3G will give us a more intuitive feel)

Image preloading is already done here, and when our network speed is good enough to get rid of some of the problems with image preloading, we can just use ABigImage’s setSrc method and remove the proxy class, so we don’t have to change the ontology code at all, which is easy to maintain.

// When the network speed is fastlet aImage = new ABigImage();
aImage.setSrc('image url')
Copy the code

conclusion

  • The proxy mode conforms to the open and closed principle.
  • The proxy mode makes the code easier to maintain.
  • Ontology objects generally have the same methods as proxy objects, so consumers do not know whether they are requesting an ontology object or a proxy object.

All examples of proxy mode can be viewed in Demo

Repository source: javascript-Design Patterns