2016-12-09 5 views
0

У меня есть следующий переключатель заявление:Refactor большой переключатель заявление

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

Я думаю, что оператор switch, вероятно, стоит сохранить. Я бы начал рефакторинг, вытащив отдельные блоки дела в свои собственные функции. Это облегчит их тестирование и отладку. –

+0

Наименее общий знаменатель, как представляется, инициализировать указатель; для (пусть i = 0; i

ответ

0

(Это, вероятно, принадлежит на 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.

Простые объекты или непосредственные функции могут быть значительно меньшей реализацией, хотя и не обязательно легче рассуждать. У них также есть преимущество в том, что вы можете закрыть переменные, которые у вас уже есть.

+0

Так что это не большая польза для реализации этого, потому что будет гораздо больше кода, чем раньше, и логика только перемещается. – Piu130

+0

@ Piu130 Зависит. Разрыв его обеспечивает большую гибкость и позволяет проводить более тесное тестирование в отдельности и требует интеграционного теста, чтобы обеспечить доступ к соответствующему классу или объекту. Не уверен, что я соглашусь с * большим * большим количеством кода, или если больше кода обязательно плохо. –

 Смежные вопросы

  • Нет связанных вопросов^_^