我正在研究Node.js的EventEventEventEvent。我正在尝试创建一个面包店,当它烤面包时,如果客户有钱,他们会自动购买面包。尽管如此,我还想创建一个客户列表,我可以添加或删除客户,他们只会在添加时监听事件,而在删除时不会再监听。这是我一直在做的事情:
bakery.js**
const eventEmitter = require('./event-emitter.js');
const events = require('./events.js');
class Bakery {
_breads;
_customers;
_breadPrice;
constructor(breadPrice) {
this._breads = 0;
this._customers = [];
this._breadPrice = breadPrice;
}
get breadPrice() {
return this._breadPrice;
}
bakeBreads(breadsQuantity) {
this._breads += breadsQuantity;
eventEmitter.emit(events.BREAD_BAKED, breadsQuantity);
}
addCustomer(customer) {
// How would i do?
this._customers.push(customer);
eventEmitter.on(events.BREAD_BAKED, (breads) => {
customer.buyBread(breads);
})
customer.bakery = this;
}
removeCustomer(customer) {
// How would i do?
}
}
module.exports = Bakery;
字符串
customer.js
class Customer {
_customerName;
_maxPrice;
_moneyAmount;
_bakery;
constructor(customerName, maxPrice, moneyAmount, bakery) {
this._maxPrice = maxPrice;
this._moneyAmount = moneyAmount;
this._bakery = bakery;
this._customerName = customerName;
}
set bakery(bakery) {
this._bakery = bakery;
}
buyBread() {
if (this._moneyAmount >= this._bakery.breadPrice) {
this._moneyAmount -= this._bakery.breadPrice;
console.log(`Customer ${this._customerName} bought a bread costing ${this._bakery._breadPrice}`);
return;
}
console.log(`${this._customerName} doesn't have enough money to buy a bread`);
}
}
module.exports = Customer;
型
main.js
const Bakery = require('./bakery.js');
const Customer = require('./customer.js');
const bakery = new Bakery(2.5)
const johnRich = new Customer('John', 1, 10);
const martinPoor = new Customer('Martin', 0.3, 1);
型
你对如何正确实施它有什么想法吗?
1条答案
按热度按时间jaql4c8m1#
OP问题的一个可能的解决方案是两个主要的设计更改,这也会导致模型和实现中的更多更改。
Map
示例中的customer名称下,其中customer的名称应该是唯一的。因此,对
Customer
类的更改比对Bakery
类的更改侵入性更小。customer.js
字符串
面包店需要经历的变化如下...
addCustomer
/removeCustomer
1.基于Map的存储
***a)**如何发出事件和传递数据。
***B)**如何取消/注册客户的面包购买处理程序。
通过实施第**2)点,顾客应该能够从任何一家面包店购买面包。
这是OP设计的直接结果,即在面包店的客户列表中添加/删除客户,并发送 “面包烘烤” 事件。因此,将单个面包店示例分配给客户对象是没有价值的。另一方面,应该清楚的是,调度的数据不仅必须提供新鲜烘焙的面包片的数量,而且还必须提供负责烘焙
这直接导致客户的
buyBread
方法的arguments-signature发生变化。它的第一个参数必须是面包店引用,第二个参数必须是要购买的面包数量,默认值为1。此外,还有一些针对隐私和字段保护的更改。OP使用下划线来注解伪私有字段。另一方面,OP使用get方法来访问这些已经公开的字段,例如面包店的
_breadPrice
与breadPrice
。在这种情况下,以及其他一些情况下,使用真正的private properties是完全可以的此外,最重要的是,OP似乎为每个要创建的
Bakery
示例使用单个EventEmitter
示例。但是正确的目标事件/数据分发依赖于面包店示例与其所有注册客户之间的松散关系。因此,每个面包店对象都需要自己的EventEmitter
示例。bakery.js
型
编辑
在下一个代码迭代中,关于购买和销售的建模方法确实需要改进。
一个可能的解决方案是实现面包店的
sellBread
方法,该方法传递客户参考和要购买的面包片的数量。该方法将控制买方/卖方交易是否成功的整个验证。客户同样将具有buyBread
方法,该方法传递面包店-这个方法只会转发到传递的bakery-reference的sellBread
方法,但是会返回一个交易结果,要么是成功的,要么是交易失败的原因。下面提供的示例代码实现了一个
Bakery
类,它还扩展了EventTarget
,以演示如何在Bakery
示例中直接使用addEVentListener
/removeEventListener
和dispatchEvent
。最重要的是还有其他代码改进,比如验证传递给
addCustomers
/removeCustomers
的项是否是有效的客户对象。