Application of design pattern in TypeScript - agent pattern

Definition

The proxy pattern is to provide a surrogate, or placeholder, for an object to control access to it.

Realization

Idea: hide the classes and methods that the client really calls, and only expose the proxy class to the client.

Simple example:

// Food service interface
interface FootService {
  makeChicken (salt: string): void;
  makeNoodle (salt: string): void
}

// Food interface
class Foot {

  // type
  public type: string

  // weight
  public salt: string

  public constructor (type: string, salt: string) {
    this.type = type
    this.salt = salt
    this.cook()
  }

  // cook
  public cook (): void {
    console.log(`Type: ${this.type},Weight: ${this.salt}`)
  }
}

// Real food service
class FootServiceReal implements FootService {
  public chicken: Foot
  public Noodle: Foot

  public makeChicken (salt: string): any {
    this.chicken = new Foot('chicken', salt)
  }
  public makeNoodle (salt: string): any {
    this.Noodle = new Foot('noodle', salt)
  }
}

// Food service agency
class FootServiceProxy implements FootService {
  // Real implementation class
  private footServiceReal: FootServiceReal

  private prepareFood () {
    if (!this.footServiceReal) {
      this.footServiceReal = new FootServiceReal()
    }
  }

  public makeChicken () {
    console.log('Start making chicken right now')
    console.log('==========')
    this.prepareFood()
    this.footServiceReal.makeChicken('500g')
    console.log('==========')
    console.log('Chicken is ready')
  }

  public makeNoodle () {
    console.log('Start making noodles now')
    console.log('==========')
    this.prepareFood()
    this.footServiceReal.makeNoodle('100g')
    console.log('==========')
    console.log('Noodles are ready')
  }
}

const foot = new FootServiceProxy()
foot.makeChicken()
console.log('========')
foot.makeNoodle()

Cache agent is quite common. It can provide cache for some expensive operation results. In the next operation, if the parameters passed in are the same as before, the previously stored operation results can be returned directly.

// addition
function add (arg: Array<number>): number {
  console.log('Add once')
  return arg.reduce((prev: number, cur: number): number => prev + cur, 0)
}

// multiplication
function mul (arg: Array<number>): number {
  console.log('Perform a multiplication calculation')
  return arg.reduce((prev: number, cur: number): number => prev * cur, 1)
}

// agent
class CalculateProxy {
  private cache: Object = {}
  private fn: Function

  public constructor (fn: Function) {
    this.fn = fn
  }

  public calculate (...arg: Array<number>): void {
    const str: string = arg.join(',')
    if (str in this.cache) {
      return this.cache[str]
    } else {
      return this.cache[str] = this.fn(arg)
    }
  }
}

const addCalculateProxy = new CalculateProxy(add)
console.log(addCalculateProxy.calculate(1, 2, 3, 4))
console.log(addCalculateProxy.calculate(1, 2, 3, 4))
console.log('=========')
const mulCalculateProxy = new CalculateProxy(mul)
console.log(mulCalculateProxy.calculate(1, 2, 3, 4))
console.log(mulCalculateProxy.calculate(1, 2, 3, 4))

Posted by chenggn on Sat, 02 May 2020 20:52:44 -0700