Параметры: +DRY, -KISS

В программировании (да и в жизни в целом) есть два типа мышления — условиями и связями. Второе, на сегодняшний день, является самым лучшим и оптимальным видом мышления, ведь благодаря ему не приходится останавливаться, вы можете его переиспользовать, и, тем самым, не повторяться. Но оно чуть сложнее первого типа мышления.

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

Рассмотрим на примере кода. У нас есть enum — список типов данных на служебном языке:

STRING

BOOL

DATE

INTEGER

DATETIME

DECIMAL

Мы должны обработать этот список так, чтобы выводить человеко-читаемые слова в зависимости от типа данных.

Условным (первым) типом мышления мы бы сделали так:

1) Добавили выборку switch в компоненте

component.ext

switch (type) { 
  case 'DATE': 
    return 'Дата' 
  case 'STRING': 
    return 'Строка' 
  case 'BOOL': 
    return 'Булево' 
  case 'INTEGER': 
    return 'Число' 
 case 'DECIMAL': 
    return 'Десятичное' 
 case 'DATETIME': 
    return 'Время'
 default:
    return 'Без значения'
} 

Типом мышления "Связи" (вторым) мы бы сделали так:

1) Создадим глобально (или локально) config file:

configs/data-types.js

// так же будет использоваться в select компонентах 
export const dataTypes = [ 
  { 
    name: 'Строка', 
    value: 'STRING' 
  },
  {
    name: 'Булево', 
    value: 'BOOL' 
  },
  {
    name: 'Дата', 
    value: 'DATE' 
  },
  { 
    name: 'Число', 
    value: 'INTEGER' 
  }, 

  { 
    name: 'Время', 
    value: 'DATETIME' 
  }, 

  { 
    name: 'Десятичное', 
    value: 'DECIMAL' 
  } 
] 

2) Добавим рядом вид-по-ключу (позволяет сделать вид "value: name" из массива):

configs/data-types.js

export const dataTypesKeys = {} 

dataTypes.forEach(({ value, name }) => dataTypesKeys[value] = name)

3) Добавим выборку в компоненте:

component.ext

import { dataTypesKeys } from 'src/configs/data-types'

const func = type => dataTypesKeys[type]

func('BOOL') // Булево

Подведем итоги способов мышления

1) С помощью первого образа мышления мы получили довольно простой механизм связи текста к служебным данным, но переиспользовать это мы уже не способны (лишь вынести в отдельную export функцию, но тогда мы потеряем чистоту статичных данных). А это большой минус, так как мы нарушаем DRY, хоть и потакаем KISS.

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

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

4) Из минусов второго примера можно отметить, что при получении не записанного type мы получим undefined, а в первом мы способны поставить default опцию в switch и обработать это значение. Но нам стоит уточнить один важный факт: на back-end и на front-end статичные enum-ы должны иметь одинаковый набор данных, иначе это ожидаемая ошибка. Этот случай легко обходится во втором способе мышления добавлением нескольких символов:

component.ext

import { dataTypesKeys } from 'src/configs/data-types'

const func = type => dataTypesKeys[type] ?? 'Без значения' // look at me

func('BOOL') // Булево

5) Этот подход работает только на статичных данных, динамичные же мы получает с нашего API.

6) Таким образом мы создали единственный главный источник истины и положили его глобально в директорию configs.