Сделайте свой JS-код более элегантным и удобным в сопровождении

JavaScript спецификация кода
Сделайте свой JS-код более элегантным и удобным в сопровождении
  • Автор: Чен Даютоу
  • гитхаб:KRISACHAN

В процессе разработки Ютоу подытожил некоторый опыт программирования в оптимизированной разработке.Конечно, этот опыт был подытожен предшественниками.На этот раз я поделюсь им с вами.Конечно, этот опыт не обязательно является передовым опытом.Читатели кто заинтересован или имеет другое мнение, может обсудить это с Юто.

отвергнуть магию

Как мы все знаем, волшебство происходит следующим образом:

О нет. .

В мире программирования тоже есть магия, обычно называемая магическими числами, магическими переменными, магическими строками. Например это:

const a = await abcdefg();
console.log(a === 200);
const b = await asdfgh();
if (b === 0) {
} else if (b === 1) {
} else if (b === 2) {};
for (let i = 0; i < 10; i++) {};

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

Код, написанный таким образом, непонятен, сложен в сопровождении и содержит множество скрытых ошибок. легко сломать ноги, 👨‍🦽 )

Так как же писать изящнее?

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

Во-первых, это семантика. Одним из них является семантика переменных, констант, таких как:

const SUCCESS_STATUS = 200;
const requestStatus = await getStatus();
console.log(requestStatus === SUCCESS_STATUS);
const userRole = await getUserRole();
const GUEST_CODE = 0;
const USER_CODE = 1;
const ADMIN_CODE = 2;
if (userRole === GUEST_CODE) {
} else if (userRole === USER_CODE) {
} else if (userRole === ADMIN_CODE) {};
const MAX_NUM = 10;
const MIN_NUM = 0;
for (let currentNum = MIN_NUM; currentNum < MAX_NUM; currentNum++) {};

Общее правило состоит в том, чтобы использовать строчные буквы для переменных и прописные для констант, а имя переменной сделать семантическим, поэтому, когда вы видите этот код, вы можете сразу увидеть, что он делает, вместо того, чтобы тратить время на чтение контекста или на догадки.

перечислить

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

Согласно Википедии: в математике и теории информатики перечисление набора — это программа, которая перечисляет все члены некоторого конечного набора последовательностей или количество объектов определенного типа. Эти два типа часто (но не всегда) пересекаются.

По сути, это способ организации набора связанных переменных. Преимущество перечисления в том, что им удобно управлять несколькими состояниями и оно более читабельно. Например:

const ROLES = {
  GUEST: 0,
  USER: 1,
  ADMIN: 2
};
const userRole = await getUserRole();
if (userRole === ROLES.GUEST) {
} else if (userRole === ROLES.USER) {
} else if (userRole === ROLES.ADMIN) {};

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

режим стратегии

Википедия говорит: как шаблон проектирования программного обеспечения, шаблон стратегии означает, что объект имеет определенное поведение, но в разных сценариях поведение имеет разные алгоритмы реализации.

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

Конкретные примеры следующие:

const ROLES = {
  GUEST: 0,
  USER: 1,
  ADMIN: 2
};
const ROLE_METHODS = {
  [ROLES.GUEST]() {},
  [ROLES.USER]() {},
  [ROLES.ADMIN]() {},
};
const userRole = await getUserRole();
ROLE_METHODS[userRole]();

Из приведенного выше письма мы можем знать, что когда нам нужно добавить роли или изменить количество ролей, нам нужно только изменитьROLESсоответствующие поля в , иROLE_METHODSметод вif...elseКод извлекается, степень детализации лучше, а обслуживание лучше.

больше в состоянии

В дополнение к вышеперечисленным методам мы также можем использовать «условие«Концепция написания кода. Прежде чем рассматривать код, давайте сначала поймем, что такое «Конечный автомат».

Согласно объяснению Википедии: Конечный автомат (англ. конечное число состояний и математические вычислительные модели поведения, такие как переходы и действия между этими состояниями.

Например, мы знакомы сPromise, он находится в наборе состояний:PENDIN,FULFILLED,REJECTEDКонечный автомат с односторонним потоком между ними.

Концепция конечного автомата аналогична концепции шаблона стратегии, и его реализация также аналогична. Самая большая разница здесь заключается в том, что "семантика".

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

const 吃 = {
  沙县大酒店() {
    吃云吞()
  },
  开封菜() {
    吃汉堡()
  },
  在家() {
    吃外卖()
  }
};

Здесь, если мы голодны, мы можем только沙县大酒店(),开封菜(),在家()Выберите одно из этих состояний.

Вы не можете съесть их все, за следующими исключениями, конечно. . .

Если это шаблон состояния, будет такая ситуация:

const 打工人 = {
  起床() {},
  上班() {},
  加班() {},
  下班() {}
};
// 早上6点
打工人.起床();
// 早上9点
打工人.上班();
// 晚上6点
打工人.加班();
// 晚上12点
打工人.下班();

Рабочие здесь выполняют разные задачи в разное время, это рабочий режим, о нет, статусный режим. Время здесь состояние.

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

Пользовательский интерфейс, отображаемый в разных состояниях, также отличается, поэтому после того, как мы разделим модули в разных состояниях, код станет намного понятнее.VueПример кода:

// contants.js
export const ORDER_STATUS = {
  INIT: 0, // 初始化
  CREATED: 1, // 订单创建
  ARREARAGE: 2, // 待支付
  PURCHASED: 3, // 已购买
  SHIPPED: 4, // 已发货
  COMPLETED: 5 // 已完成
};
// order.vue
<template>
  <div>
        <section v-if="orderIsInit"></section>
        <section v-if="orderIsCreated"></section>
        <section v-if="orderIsArrearage"></section>
        <section v-if="orderIsPurchased"></section>
        <section v-if="orderIsShipped"></section>
        <section v-if="orderIsCompleted"></section>
  </div>
</template>

<script>
  import ORDER_STATUS from './contants';
  import eq from 'lodash';
  
  export default {
    computed: {
      /**
       * @func
       * @name orderIsInit
       * @desc 判断订单是否初始化的状态
       * @returns {string} 判断订单是否初始化的状态
       */
      orderIsInit() {
        return eq(this.orderStatus, ORDER_STATUS.INIT);
      },
      /**
       * @func
       * @name orderIsCreated
       * @desc 判断订单是否已创建的状态
       * @returns {string} 订单是否已创建
       */
      orderIsCreated() {
        return eq(this.orderStatus, ORDER_STATUS.CREATED);
      },
      /**
       * @func
       * @name orderIsArrearage
       * @desc 判断订单是否未付款的状态
       * @returns {string} 订单是否未付款
       */
      orderIsArrearage() {
        return eq(this.orderStatus, ORDER_STATUS.ARREARAGE);
      },
      /**
       * @func
       * @name orderIsPurchased
       * @desc 判断订单是否已购买的状态
       * @returns {string} 订单是否已购买
       */
      orderIsPurchased() {
        return eq(this.orderStatus, ORDER_STATUS.PURCHASED);
      },
      /**
       * @func
       * @name orderIsShipped
       * @desc 判断订单是否已发货的状态
       * @returns {string} 订单是否已发货
       */
      orderIsShipped() {
        return eq(this.orderStatus, ORDER_STATUS.SHIPPED);
      },
      /**
       * @func
       * @name orderIsCompleted
       * @desc 判断订单是否已完成的状态
       * @returns {string} 订单是否已完成
       */
      orderIsCompleted() {
        return eq(this.orderStatus, ORDER_STATUS.COMPLETED);
      },
    },
    data() {
      return {
        orderStatus: ORDER_STATUS.INIT // 订单状态
      }
    },
    methods: {
      /**
       * @func
       * @name getOrderStatus
       * @desc 判断订单状态
       * @returns {string} 返回当前订单状态
       */
      async getOrderStatus() {}
    },
    async created() {
      this.orderStatus = await this.getOrderStatus();
    }
  }
</script>

Разделите компоненты страницы по состоянию для достижения независимости и автономии, что может не только предотвратить связывание кода, облегчить обслуживание и отладку, но и облегчить самотестирование разработчика.Если вам нужно увидеть эффект отображения различных состояний, вам нужно только вручную указатьorderStatusЗадание можно сделать, удобно и быстро.

лицом к лицу

Согласно объяснению Википедии: Аспектно-ориентированное программирование (АОП, также переводится как аспектно-ориентированное программирование, секционно-ориентированное программирование) — это идея программирования в области компьютерных наук, которая направлена ​​на решение сквозных задач. Дальнейшее отделение от основной части бизнеса для улучшения модульность программного кода.

Подсчитано, что вышеприведенный текст никто не читает, забудьте, давайте сразу к коду.

Давайте вернемся к приведенному выше сценарию рабочих рабочих. Предположим, босс хочет знать время до и до окончания каждого состояния рабочих рабочих и что делать. Так что же нам делать? В это время нам нетрудно подумать, что мы можем написать код прямо в функцию состояния, например:

const 打工人 = {
  起床() {
    老板.start();
    打工人.do();
    老板.end();
  },
  上班() {
    老板.start();
    打工人.do();
    老板.end();
  },
  加班() {
    老板.start();
    打工人.do();
    老板.end();
  },
  下班() {
    老板.start();
    打工人.do();
    老板.end();
  }
};
// 早上6点
打工人.起床();
// 早上9点
打工人.上班();
// 晚上6点
打工人.加班();
// 晚上12点
打工人.下班();

Но таким образом рабочий сразу понимает, что начальник следит за его жизнью.Если мы хотим, чтобы нас не заметили (не затрагивая бизнес-логику), то мы можем либо использоватьAOPспособ реализации. код показывает, как показано ниже:

import eq from 'lodash';
const TYPES = {
  FUNCTION: 'function'
}
const 老板监控中的打工人 = new Proxy(打工人, {
    get(target, key, value, receiver) {
        console.log('老板开始看你了~');
      	const res = Reflect.get(target, key, value, receiver);
      	const 打工人任务 = eq(typeof res, TYPES.FUNCTION) ? res() : res;
        console.log('老板开始记你小本本了~');
        return () => 打工人任务;
    }
});

Итак, мы можем увидеть следующие результаты:

Таким образом, мы можем легко и просто следить за работой, которую гастарбайтеры делают каждый день, и не дать гастарбайтерам узнать, потому что капиталисты просто плачут, когда слышат это.

постскриптум

Приведенное выше резюме — лишь малая часть многих шаблонов спецификаций программирования, таких какS.O.L.I.DА остальные 20 паттернов проектирования в этой статье не упоминаются, место ограничено, прошу меня простить.