Рефакторинг: Сжигание мозгов Очистка суждений

JavaScript
Рефакторинг: Сжигание мозгов Очистка суждений

При написании бизнес-кода вы часто сталкиваетесь с суждениями.Сталкиваясь с различными бизнес-сценариями, знаете ли вы лучшее решение?

Давайте посмотрим на базовый случай:

Первичный: если еще если челнок сделан

Промежуточный: переключение регистра, если еще, полиморфизм, обертывание шаблонами проектирования

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


Приготовьте для себя чашку капучино 82-летней выдержки и осторожно насладитесь им.

Сначала посмотрите на код

Требование: оценить сегодняшнюю рабочую ситуацию, текущее время и ход работы как условия

    {
        period:afteroon,// 当前时间:afternoon || night
        workProgress:start,  // 工作进度: start || end
    }

if-else

    if(period === 'afternoon'){
        上班
    }else if(period === 'night' && workProgress !== 'end'){
        加班
    }else {
        下班
    }

Преимущества: if else является наиболее распространенным и наиболее знакомым суждением для всех программистов и может содержать сложные условия.

Недостаток: слишком много логики может стать очень многословным и трудным для понимания.

Если не смотреть на выражения «идти на работу» и «работать сверхурочно», сможете ли вы быстро понять, какое состояние соответствует уходу с работы?

switch-case

    switch(period){
        case 'afternoon':
           上班
        break;
        case 'night' && workProgress:
           下班
        break;
        case  'night' && workProgress !== 'end':
           加班
        break;
        default:
           肝就完事
        break;
    }

Достоинства: Он более лаконичен и интуитивно понятен при различных параллельных условиях, может выскакивать и имеет лучшую производительность.

Недостатки: Слишком много логики с одним и тем же условием станет похоже на связку ног, вложенность и выражения, не являющиеся одним и тем же условием, затруднены.

Когда условия усложняются и добавляется состояние (фиксированные сверхурочные по будням, вторникам и четвергам), можно ли его сохранить?

Тернарные операции: , короткое замыкание && ||

Достоинства: Код более лаконичный и доработанный

Недостатки: чрезмерно сложные тернарные операции не являются семантически сильными и сложными в обслуживании.

    period === 'afternoon'? '上班' : (workProgress === 'end'? '下班' : '加班')

Как и выше, условия могут усложняться и поддерживаться, и для понимания этой строки кода требуется немного времени. . .

Шаблон стратегии/шаблон состояния Инкапсуляция шаблона проектирования

Преимущества: прост в обслуживании, несколько интерпретируемый, полиморфный.

Недостатки: увеличивается сложность кода и требуется определенная возможность абстракции.

    const AllState = {
        '上班':onWork,
        '下班':endWork,
        '加班':stillWork,
    }
    const period = 'night';
    const workProgress  = 'start';
     
    function onWork() {
        return period === 'afternoon';
    }
    
     function endWork() {
        return period === 'night' && workProgress === 'end';
    }
    
     function stillWork() {
        return period === 'night' && workProgress === 'start';
    }
    
    function getWorkState() {
        let state = '肝就对了';
        Object.keys(AllState).some((result) =>{
            if(AllState[result]()){
                state = result;
                return true;
            };
        });
        console.log(state);
        return state;
    }
    
    const workState = getWorkState();

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

Семантический

Вы новый сотрудник, ваш начальник похлопал вас по плечу и сказал, что это код, оставленный предыдущими 3-мя уволившимися сотрудниками.

    if(state === 1){
        // 一gi窝里giaogiao
    }else if(state === 2){
        // 左边画个龙右边写个bug
    }else if(state === 3){
        //do something
    }
    .....以此类推

Секрет быстрого роста новичков в том, чтобы писать проекты без интерфейсных документов и без требований к прототипам, которых полно проектов с таким цифровым статусом.

Замена условий суждения объектами

    const stateType = {
        start: 1,  // 开始 
        doing: 2,  // 进行中
        end: 3,    // 结束
    }
    
    if(state === stateType['start']){
        //  一gigiaogiao里giaogiao
    }else if(state === stateType['doing']){
        // 左边画个龙右边写个bug
    }else if(state === stateType['end']){
        // do something
    }

Не думайте, что еще один объектный код станет лишним, ключ в этом объекте — лучший комментарий для сопровождения этого кода.

Замена условий суждения функциями

Если взять в качестве примера фестиваль электронной коммерции, то требуется, чтобы девочки старше 18 лет имели больше скидок, чем мальчики.

    if(sex==='feMale' && age>18) {
        charge = (quantity * count) - 800; // 男生优惠800元
    }else{
        charge = (quantity * count)*0.8 - 500; // 女生8折再优惠500元
    }
Модификация по условиям разложения

1. Функции заменяют условия суждения

   function allowAge(){
       return sex==='feMale' && age>18;
   }

2. Функция выполнения декомпозиции

    function  maleCharge(){
        return (quantity * count) - 800;
    }
    
     function  femaleCharge(){
        return (quantity * count)*0.8 - 500;
    }

3. Сведен к простому тернару

    charge = allowAge() ? femaleCharge() : maleCharge();

Операторы выполнения инкапсулированы, сделаны короткими и понятными.

Сан-операция

1. Если есть условие невыполнения, чтобы уменьшить ненужный код, возвращайтесь заранее

    function allowAge(age){
         if (age<'18') throw new Error('No adult!');
         // 正常
    }

2. Установите значения по умолчанию для параметров, чтобы вам не нужно было делать обработку неопределенного типа

     function  maleCharge(arg){ 
        const count  = arg || 5;
        return (quantity * count) - 800;
    }
    
    // 优化后
    
    function  maleCharge(count = 5){ 
        return (quantity * count) - 800;
    }

3. Поместите несколько простых условий в объект массива, используя include

    if(fruit === 'apple'||fruit === 'banana'||fruit === 'lemon') eatFruit()
    
    if(['apple','banana','lemon'].includes(fruit)) eatFruits()

4. Когда состояний много, можно упаковать таким образом

Карта в es6 позволяет использовать объекты в качестве ключей

    const period = 'night';
    const workProgress = 'end';
    const worklist = () => { 
        return new Map([
          [{period:'morning',workProgress:'start'},()=>{/* 上班 */}],
          [{period:'afternoon',workProgress:'end'},()=>{/* 上班 */}],
          [{period:'night',workProgress:'doing'},()=>{/* 加班 */}],
          [{period:'night',workProgress:'start'},()=>{/* 加班 */}],
          [{period:'night',workProgress:'end'},()=>{/* 下班 */}],
          //...
        ])
    }

Использование объектов в качестве ключей может хранить несколько данных (условий)

    function getWorkState (){
      const todayWorkState = [...worklist()].filter(([key])=>(key.period === period && key.workProgress === workProgress));
      return todayWorkState[0][1]();
    }
    const workState = getWorkState ();

Если после прочтения вы работаете сверхурочно, значит, вы это понимаете!

Если вы считаете, что это хорошо, пожалуйста, в хорошем качестве, ставьте лайки, подписывайтесь, пересылайте и комментируйте, ведь нужно правильно питаться.

Чтобы узнать больше, обратите внимание на технический паблик: ihap technology blackhole! ! !