我应该如何处理多个依赖于订单的条件?
How should I deal with multiple order-dependent conditions?
我有多个并发条件,其中顺序取决于条件。我想出了多种方法来处理这个问题,我需要帮助从我准备的几种解决方案中选择最佳解决方案。需要考虑的事项是:性能、可重用性、可读性、内存消耗。
方法一:定义多个嵌套的 switch case
var collision = {
detect1: function(subject, target){
// multiple switch cases
var shapes = {};
shapes[subject.type] = subject;
shapes[target.type] = target;
switch(subject.type) {
case 'rectangle':
switch(target.type) {
case 'ellipse':
return this.rectWithEllipse(subject, target);
}
break;
case 'ellipse':
switch(target.type) {
case 'rectangle':
return this.rectWithEllipse(target, subject);
}
}
},
方法 2:将类型存储在对象注册表中并根据参数测试切换顺序
detect2: function(subject, target){
// object registry and place switch
var shapes = {};
shapes[subject.type] = subject;
shapes[target.type] = target;
var shape1 = subject;
var shape2 = target;
var reverseShapeOrder = function() {
shape2 = target;
shape1 = subject;
};
if ( shapes.rectangle && shapes.ellipse ) {
if (subject.type === 'ellipse') {
reverseShapeOrder();
return this.rectWithEllipse(shape1, shape2);
}
}
},
方法 3:将类型连接到字符串并根据 indexOf 测试顺序切换顺序。
detect3: function(subject, target) {
// string concat and decoding with place switch
var shapeString = subject.type + target.type;
var rectIndex = shapeString.indexOf('rectangle');
var ellipseIndex = shapeString.indexOf('ellipse');
var pointIndex = shapeString.indexOf('point');
var shape1 = subject;
var shape2 = target;
var reverseShapeOrder = function() {
shape2 = target;
shape1 = subject;
};
if (rectIndex && ellipseIndex) {
if (ellipseIndex < rectIndex) {
reverseShapeOrder();
}
return this.rectWithEllipse(shape1, shape2);
}
},
方法 4:标准的传统 if-else 语句
// traditional logic
detect4: function(subject, target) {
if (subject.type === 'rectangle' && target.type === 'ellipse') {
return this.rectWithEllipse(subject, target);
}
else if (subject.type ==='ellipse' && target.type === 'rectangle') {
return this.rectWithEllipse(target, subject);
}
},
rectWithEllipse: function(rect, ellipse) {
return false;
}
};
方法 5:即时 select 或具有参考功能(感谢即时 select 或@Bergi 的建议)
detect5: function(subject, target) {
return this[subject.type + '_with_' + target.type](subject, target);
},
rect_with_ellipse: function(rect, ellipse) {
return false;
},
ellipse_with_rect: function(rect, ellipse) {
this.rect_with_ellipse(ellipse, rect);
}
};
请帮助我 select 最好的解决方案并理解为什么它是最好的。谢谢
请记住,完整的组合列表会像这样更大:
rectWithPoint: function(rect, point) {
return false;
},
rectWithEllipse: function(rect, ellipse) {
return false;
},
rectWithRect: function(rect, rect) {
return false;
},
ellipseWithPoint: function(ellipse, point) {
return false;
},
ellipseWithEllipse: function(ellipse, ellipse) {
return false;
}
我会定义一个映射如下,这将使扩展变得容易:
targets: {
rectangle: {
point: function rectWithPoint(rect, point) {
return false;
},
ellipse: function rectWithEllipse(rect, ellipse) {
return false;
},
rectangle: function rectWithRect(rectLhs, rectRhs) {
return false;
}
},
ellipse: {
point: function ellipseWithPoint(ellipse, point) {
return false;
},
ellipse: function ellipseWithEllipse(ellipseLhs, ellipseRhs) {
return false;
}
}
},
detect5: function (subject, target) {
var tmp, candidates = this.targets[subject];
if (!candidates) {
tmp = subject;
subject = target;
target = tmp;
candidates = this.targets[subject];
}
if (candidates && candidates.hasOwnProperty(target)) {
return candidates[target].call(this, subject, target);
}
return false;
}
我有多个并发条件,其中顺序取决于条件。我想出了多种方法来处理这个问题,我需要帮助从我准备的几种解决方案中选择最佳解决方案。需要考虑的事项是:性能、可重用性、可读性、内存消耗。
方法一:定义多个嵌套的 switch case
var collision = {
detect1: function(subject, target){
// multiple switch cases
var shapes = {};
shapes[subject.type] = subject;
shapes[target.type] = target;
switch(subject.type) {
case 'rectangle':
switch(target.type) {
case 'ellipse':
return this.rectWithEllipse(subject, target);
}
break;
case 'ellipse':
switch(target.type) {
case 'rectangle':
return this.rectWithEllipse(target, subject);
}
}
},
方法 2:将类型存储在对象注册表中并根据参数测试切换顺序
detect2: function(subject, target){
// object registry and place switch
var shapes = {};
shapes[subject.type] = subject;
shapes[target.type] = target;
var shape1 = subject;
var shape2 = target;
var reverseShapeOrder = function() {
shape2 = target;
shape1 = subject;
};
if ( shapes.rectangle && shapes.ellipse ) {
if (subject.type === 'ellipse') {
reverseShapeOrder();
return this.rectWithEllipse(shape1, shape2);
}
}
},
方法 3:将类型连接到字符串并根据 indexOf 测试顺序切换顺序。
detect3: function(subject, target) {
// string concat and decoding with place switch
var shapeString = subject.type + target.type;
var rectIndex = shapeString.indexOf('rectangle');
var ellipseIndex = shapeString.indexOf('ellipse');
var pointIndex = shapeString.indexOf('point');
var shape1 = subject;
var shape2 = target;
var reverseShapeOrder = function() {
shape2 = target;
shape1 = subject;
};
if (rectIndex && ellipseIndex) {
if (ellipseIndex < rectIndex) {
reverseShapeOrder();
}
return this.rectWithEllipse(shape1, shape2);
}
},
方法 4:标准的传统 if-else 语句
// traditional logic
detect4: function(subject, target) {
if (subject.type === 'rectangle' && target.type === 'ellipse') {
return this.rectWithEllipse(subject, target);
}
else if (subject.type ==='ellipse' && target.type === 'rectangle') {
return this.rectWithEllipse(target, subject);
}
},
rectWithEllipse: function(rect, ellipse) {
return false;
}
};
方法 5:即时 select 或具有参考功能(感谢即时 select 或@Bergi 的建议)
detect5: function(subject, target) {
return this[subject.type + '_with_' + target.type](subject, target);
},
rect_with_ellipse: function(rect, ellipse) {
return false;
},
ellipse_with_rect: function(rect, ellipse) {
this.rect_with_ellipse(ellipse, rect);
}
};
请帮助我 select 最好的解决方案并理解为什么它是最好的。谢谢
请记住,完整的组合列表会像这样更大:
rectWithPoint: function(rect, point) {
return false;
},
rectWithEllipse: function(rect, ellipse) {
return false;
},
rectWithRect: function(rect, rect) {
return false;
},
ellipseWithPoint: function(ellipse, point) {
return false;
},
ellipseWithEllipse: function(ellipse, ellipse) {
return false;
}
我会定义一个映射如下,这将使扩展变得容易:
targets: {
rectangle: {
point: function rectWithPoint(rect, point) {
return false;
},
ellipse: function rectWithEllipse(rect, ellipse) {
return false;
},
rectangle: function rectWithRect(rectLhs, rectRhs) {
return false;
}
},
ellipse: {
point: function ellipseWithPoint(ellipse, point) {
return false;
},
ellipse: function ellipseWithEllipse(ellipseLhs, ellipseRhs) {
return false;
}
}
},
detect5: function (subject, target) {
var tmp, candidates = this.targets[subject];
if (!candidates) {
tmp = subject;
subject = target;
target = tmp;
candidates = this.targets[subject];
}
if (candidates && candidates.hasOwnProperty(target)) {
return candidates[target].call(this, subject, target);
}
return false;
}