JSFiddle - React, Tailwind, and code Playground

by Egor Jvechkin

JavaScript

// 1. Реализуйте класс Mailbox
// Доп. задания:
// 2. Если считаете, что Mailbox не хватает еще каких-то технических функций для более готового к использованию API, добавьте их или напишите, что бы вы добавили. Если считаете, что данное API содержит какие-то проблемы с точки зрения проектирования, опишите их и предложите рефакторинг.
// 3. Какие части кода можно было бы концептуально абстрагировать из реализации Mailbox и сделать их переиспользуемыми? Попробуйте максимально разбить реализацию на переиспользуемые части.

class SingleInstance {
  constructor(instanceName) {
    if (!this.constructor._instances) { this.constructor._instances = new Map() }
    if (this.constructor._instances.has(instanceName)) { return this.constructor._instances.get(instanceName) }

    this.constructor._instances.set(instanceName, this)
  }
}

class HooksMixin {
  constructor(...hooks) {
    const addPre = function(hook) {
      if (!this.preHooks) { this.preHooks = [] }
      this.preHooks.push(hook)
    }

    const addNotify = function(hook) {
      if (!this.notifyHooks) { this.notifyHooks = [] }
      this.notifyHooks.push(hook)
    }

    this.callNotifyHooks = function(...args) {
      this.notifyHooks && this.notifyHooks.forEach(notify => notify(...args))
    }

    this.callPreHooks = function(param) {
      let counter = -1
      let errorText

      const isValid = (!this.preHooks || this.preHooks.every((preHook, index) => {
        preHook(param, (updatedParam) => {
          param = updatedParam
          counter++
        }, err => errorText = err)

        return (index === counter)
      }))

      return {result: isValid && param, err: errorText}
    }

    hooks.forEach(hook => {
      if (hook === 'pre') { this.pre = addPre }
      if (hook === 'notify') { this.notify = addNotify }
    })
  }
}

class Mailbox extends SingleInstance {
  sendMail(message) {
    const preResult = this.callPreHooks(message)

    if (preResult.result) {
     ...