我有以下switch语句:
switch (type) {
case 1: // 1 BYTE 8-bit unsigned integer
pointer = count > 4 ? offset : pointer;
for (let i = 0; i < count; i++) {
value += dataView.getUint8(pointer + i);
}
tag.value = parseInt(value, 10);
return tag;
case 3: // 3 SHORT 16-bit unsigned integer
pointer = count > 2 ? offset : pointer;
for (let i = 0; i < count; i++) {
value += dataView.getUint16(pointer + 2 * i, littleEnd);
}
tag.value = parseInt(value, 10);
return tag;
case 4: // 4 LONG 32-bit unsigned integer
pointer = count > 1 ? offset : pointer;
for (let i = 0; i < count; i++) {
value += dataView.getUint32(pointer + 4 * i, littleEnd);
}
tag.value = parseInt(value, 10);
return tag;
case 5:
...
等等。
模式每次都相同,但有一些小的变化。我该如何重构?我想重构外壳中的样式,并且我也试图删除整个开关块。那可能吗?
(这可能属于Code Review Stack Exchange。)
没有较大的上下文,就很难提供合理的重构,甚至很难确定这种重构是否值得付出努力和进行额外的维护。
简而言之,您type
需要处理许多问题。除了开关之外,您还可以实现命令模式,其中每种类型都是小类或简单对象。(使用类可以使在“执行上下文”中传递的内容稍微容易一些,该“执行上下文”包含代码段中未显示的变量。)
为了简洁起见,这是一个(非常)粗略的轮廓。
您将有一个基本类型处理程序。这结束了dataView
循环和标签值设置。由于我不知道上下文,所以我假装有一个您传入的上下文。我包含了代码段中未显示的所有变量。
(我没有包括value
,看起来您应该这样做,但我不知道它的意图。)
class BaseTypeHandler {
constructor(ctx) {
this.ctx = ctx
}
getPointer = () => throw new Error('Missing getPointer implementation')
getViewData = () => throw new Error('Missing getViewData implementation')
getValueFromDataView = () => {
let value = 0
for (let i = 0; i < this.ctx.count; i++) {
value += this.getViewData(i, pointer)
}
return value
}
getTag = () => {
const pointer = this.getPointer()
, value = this.getValueFromDataView()
this.ctx.tag.value = parseInt(value, 10)
return this.ctx.tag
}
}
每个子类均实现所需的唯一功能,此处介绍如何获取指针以及如何从中获取数据dataView
。
class Type1Handler extends BaseTypeHandler {
getPointer = () =>
this.ctx.count > 4 ? this.ctx.offset : this.ctx.pointer
getViewData = (i, pointer) =>
this.ctx.dataView.getUint8(pointer + i)
}
class Type3Handler extends BaseTypeHandler {
getPointer = () =>
this.ctx.count > 2 ? this.ctx.offset : this.ctx.pointer
getViewData = (i, pointer) =>
this.ctx.dataView.getUint16(pointer + 2 * i, littleEnd);
}
然后,将它们包装在类型处理程序的对象中:
const typeHandlers = {
1: Type1Handler,
3: Type3Handler,
4: Type4Handler
}
const handler = new typeHandlers(type)
, tag = handler.getTag()
TL; DR
除非您拥有大量此类代码,并且您不能使用数学来找出getPointer
和getViewData
实现,否则您可能要坚持使用switch
。
简单的对象或立即函数可能是一个明显较小的实现,尽管不一定容易推理。它们还具有能够关闭本地已有变量的优点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句