JSFiddle - React, Tailwind, and code Playground

by prozoroff

JavaScript

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

class Mailbox {
	constructor(name){
  	return Mailbox.lookupTable[name] || this.init(name)
  }
  
  init(name){
  	this.name = name
    this.preHooks = []
    this.notifyHooks = []
    this.sender = new MailSender()
    return Mailbox.lookupTable[name] = this
  }
  
  sendMail(message){
  	const chain = [m => this.sendAndNotify(m)].concat(this.preHooks)
  	Utils.callChain(message, chain)
  }
  
  pre(hook){
  	this.preHooks.push(hook)
  }
  
  notify(hook){
  	this.notifyHooks.push(hook)
  }
  
	sendAndNotify(message){
  	this.sender.send(message)
    Utils.callArr(message, this.notifyHooks)
  }
}

Mailbox.lookupTable = {}

class Utils {
	static callChain(data, chain){
  	function recursiveCall(data){
    	const fn = chain.pop()
    	fn && fn(data, recursiveCall)
    }
    recursiveCall(data)
  }
  
  static callArr(data, arr){
  	arr.map(a => a(data))
  }
}

class MailSender {
	send(message){
  	//console.log(`Message ${message} has been sent`)
  }
}






const mailbox = new Mailbox('name')

mailbox.pre(function (mail, send) { // pre-хуков может быть несколько или не быть совсем. Если хуков несколько, то необходимо чтобы все подтвердили отправку. 
  if (mail !== 'spam') { // если письмо удовлетворяет условию, то только тогда подтверждаем его отправку
    send(mail)
  }
})

mailbox.notify(function (mail) { // notify-хуков может быть несколько или не быть совсем
  console.log('Новое сообщение: ' + mail)
})

mailbox.sendMail('asdf') // в консоли...