我有以下开关声明:
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:
...
等等。
模式每次都是相同的,有一些小的变化。我怎么能重构这个?我想重构案例中的模式,我也试图删除整个开关块。这可能吗?
答案 0 :(得分:0)
(这可能属于Code Review Stack Exchange。)
如果没有更大的背景,很难提供合理的重构,甚至无法确定这样的重构是否值得付出努力和额外的维护。
简而言之,您需要处理一些type
。您可以实现一种命令模式,而不是一个开关,其中每个类型都是一个小类或一个简单的对象。 (使用类可以更容易地传入&#34;执行上下文&#34;其中包含未在代码段中显示的变量。)
为了简洁起见,这是一个(非常)粗略轮廓。
您拥有基本类型处理程序。这包含了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
。
简单对象或直接函数可能是一个非常小的实现,虽然不一定更容易推理。它们还具有能够关闭本地已有变量的优势。