在以下代码中 JavaScript 中实现工厂模式的正确方法
Correct way to implement a Factory pattern in JavaScript in the following code
以下代码应该为涉及 Arduino 的项目抽象温度传感器。
我有代表硬件传感器的 Sensor 函数,一个创建传感器实例的 sensorFactory 函数,以及一个存储/returns 数组中的传感器对象的 saveSensor / findSensor 函数。
var sensors = [];
const Sensor = (sensorId, sensorType, sensorName) =>{
var temperature;
let sensor = {
sensorId,
sensorType,
sensorName,
temperature,
readTemperature: (temp) => {
temperature = temp //simulates reading from hardware
},
getTemperature: () => {
console.log(temperature)
}
}
return sensor;
};
const SensorFactory = () =>({
createSensor: (sensorId, sensorType, sensorName) => {
var sensor = {};
switch(sensorType){
case "DS18B20":
sensor = Sensor(sensorId,sensorType, sensorName);
saveSensor(sensor);
return findSensor(sensorId);
break;
}
},
getSensor: (sensorId) =>{
if (sensorId){
return findSensor(sensorId);
}
return sensors;
}
});
const saveSensor = (sensor) => {
sensors.push(sensor);
};
const findSensor = (sensorId) => {
return sensors[sensorId -1];
};
module.exports = SensorFactory;
我有两个问题:
为什么我在 运行 行 console.log(JSON.stringify(sensor1))
时看不到温度变量的值?
const SensorFactory = require ("./sensor.js");
var sensorFactory = SensorFactory();
sensorFactory.createSensor (1,"DS18B20", "Cryogenic Tank");
var sensor1 = sensorFactory.getSensor(1);
sensor1.readTemperature(200);
sensor1.getTemperature(); //prints 200
sensor1.readTemperature(100); //prints 100
sensor1.getTemperature();
sensor1.readTemperature(10); //prints 10
sensor1.getTemperature();
console.log(JSON.stringify(sensor1))
预计:
{"sensorId":1,"sensorType":"DS18B20","sensorName":"Cryogenic Tank", "temperature": 10}
实际输出:
{"sensorId":1,"sensorType":"DS18B20","sensorName":"Cryogenic Tank"}
我认为以下块中的温度 (A) 是一个私有变量,因此不应从对象外部访问它,但是当我 运行 console.log(JSON.stringify(sensor1))
?
const Sensor = (sensorId, sensorType, sensorName) =>{
var temperature; <----A----private.
let sensor = {
sensorId,
sensorType,
sensorName,
temperature, <----B----I should be able to see this, right?
readTemperature: (temp) => {
temperature = temp;
console.log('readTemperature');
},
getTemperature: () => {
console.log('getTemperature');
console.log(temperature); }
}
return sensor;
};
- 我对 JS 很生疏。你能帮我理解我在概念上错在哪里吗?您将如何修改代码以使其按预期工作?
这是对现代 Javascript 的一些重构(回答了第二个问题,并且,作为副作用,也回答了第一个问题;)
class Sensor {
constructor(id, type, name) {
this.id = id
this.type = type
this.name = name
this.temperature = null
}
readTemperature(temp) {
this.temperature = temp //simulates reading from hardware
}
}
class SensorSet extends Map {
add(id, type, name) {
this.set(id, new Sensor(id, type, name))
return this.get(id)
}
}
let sensors = new SensorSet()
sensors.add(1, "DS18B20", "Cryogenic Tank")
let s1 = sensors.get(1)
s1.readTemperature(200)
console.log(s1.temperature)
s1.readTemperature(100)
console.log(s1.temperature)
s1.readTemperature(10)
console.log(s1.temperature)
console.log(JSON.stringify(s1))
@Bergi 的第二个评论是我问题的解决方案。我也听从了他的建议并删除了 returns sensorFactory 对象的 sensorFactory 函数。代码现在清楚多了。
以下代码应该为涉及 Arduino 的项目抽象温度传感器。
我有代表硬件传感器的 Sensor 函数,一个创建传感器实例的 sensorFactory 函数,以及一个存储/returns 数组中的传感器对象的 saveSensor / findSensor 函数。
var sensors = [];
const Sensor = (sensorId, sensorType, sensorName) =>{
var temperature;
let sensor = {
sensorId,
sensorType,
sensorName,
temperature,
readTemperature: (temp) => {
temperature = temp //simulates reading from hardware
},
getTemperature: () => {
console.log(temperature)
}
}
return sensor;
};
const SensorFactory = () =>({
createSensor: (sensorId, sensorType, sensorName) => {
var sensor = {};
switch(sensorType){
case "DS18B20":
sensor = Sensor(sensorId,sensorType, sensorName);
saveSensor(sensor);
return findSensor(sensorId);
break;
}
},
getSensor: (sensorId) =>{
if (sensorId){
return findSensor(sensorId);
}
return sensors;
}
});
const saveSensor = (sensor) => {
sensors.push(sensor);
};
const findSensor = (sensorId) => {
return sensors[sensorId -1];
};
module.exports = SensorFactory;
我有两个问题:
为什么我在 运行 行
console.log(JSON.stringify(sensor1))
时看不到温度变量的值?const SensorFactory = require ("./sensor.js"); var sensorFactory = SensorFactory(); sensorFactory.createSensor (1,"DS18B20", "Cryogenic Tank"); var sensor1 = sensorFactory.getSensor(1); sensor1.readTemperature(200); sensor1.getTemperature(); //prints 200 sensor1.readTemperature(100); //prints 100 sensor1.getTemperature(); sensor1.readTemperature(10); //prints 10 sensor1.getTemperature(); console.log(JSON.stringify(sensor1))
预计:
{"sensorId":1,"sensorType":"DS18B20","sensorName":"Cryogenic Tank", "temperature": 10}
实际输出:
{"sensorId":1,"sensorType":"DS18B20","sensorName":"Cryogenic Tank"}
我认为以下块中的温度 (A) 是一个私有变量,因此不应从对象外部访问它,但是当我 运行 console.log(JSON.stringify(sensor1))
?
const Sensor = (sensorId, sensorType, sensorName) =>{
var temperature; <----A----private.
let sensor = {
sensorId,
sensorType,
sensorName,
temperature, <----B----I should be able to see this, right?
readTemperature: (temp) => {
temperature = temp;
console.log('readTemperature');
},
getTemperature: () => {
console.log('getTemperature');
console.log(temperature); }
}
return sensor;
};
- 我对 JS 很生疏。你能帮我理解我在概念上错在哪里吗?您将如何修改代码以使其按预期工作?
这是对现代 Javascript 的一些重构(回答了第二个问题,并且,作为副作用,也回答了第一个问题;)
class Sensor {
constructor(id, type, name) {
this.id = id
this.type = type
this.name = name
this.temperature = null
}
readTemperature(temp) {
this.temperature = temp //simulates reading from hardware
}
}
class SensorSet extends Map {
add(id, type, name) {
this.set(id, new Sensor(id, type, name))
return this.get(id)
}
}
let sensors = new SensorSet()
sensors.add(1, "DS18B20", "Cryogenic Tank")
let s1 = sensors.get(1)
s1.readTemperature(200)
console.log(s1.temperature)
s1.readTemperature(100)
console.log(s1.temperature)
s1.readTemperature(10)
console.log(s1.temperature)
console.log(JSON.stringify(s1))
@Bergi 的第二个评论是我问题的解决方案。我也听从了他的建议并删除了 returns sensorFactory 对象的 sensorFactory 函数。代码现在清楚多了。