Two types of thinking
Options: +DRY, -KISS
In programming (and in life in general) there are two types of thinking – conditions And connections. The second, by far, is the best and optimal type of thinking, because thanks to it you don’t have to stop, you can reuse it, and thus not repeat yourself. But it is a little more complicated than the first type of thinking.
Let’s bring real life example – We have a road, transport goes along it. The first way of thinking is traffic lights that switch so that some people drive while others wait for their turn. So the second way of thinking is the absence of traffic lights and the construction of the road so that no one waits for anyone and does not stop, all movement is constant and, along its trajectory, flows from one path to another.
Let’s look at a code example. We have enum – a list of data types in a service language:
STRING
BOOL
DATE
INTEGER
DATETIME
DECIMAL
We need to process this list in such a way as to output human-readable words depending on the type of data.
With the conditional (first) type of thinking, we would do this:
1) Added a switch selection in the component
component.ext
switch (type) {
case 'DATE':
return 'Дата'
case 'STRING':
return 'Строка'
case 'BOOL':
return 'Булево'
case 'INTEGER':
return 'Число'
case 'DECIMAL':
return 'Десятичное'
case 'DATETIME':
return 'Время'
default:
return 'Без значения'
}
With the type of thinking “Connections” (second) we would do this:
1) Create a global (or local) 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) Add a view-by-key next to it (allows you to make the view “value: name” from an array):
configs/data-types.js
export const dataTypesKeys = {}
dataTypes.forEach(({ value, name }) => dataTypesKeys[value] = name)
3) Add a selection in the component:
component.ext
import { dataTypesKeys } from 'src/configs/data-types'
const func = type => dataTypesKeys[type]
func('BOOL') // Булево
Let’s sum up the ways of thinking
1) Using the first way of thinking, we got a fairly simple mechanism for linking text to service data, but we are no longer able to reuse it (just put it in a separate export function, but then we will lose the purity of static data). And this is a big minus, since we violate DRY, although we indulge KISS.
2) The second way of thinking is more complicated, but it can be reused and, thanks to it, opens up many ways to expand, for example, we can upgrade the original array into various configurations of objects or arrays, as we did at the end of the example.
3) Thanks to the second method, we can easily add static data and it will be delivered to all components and all dependencies.
4) From the minuses of the second example, it can be noted that when we receive an unrecorded type, we will get undefined, and in the first we are able to put the default option in the switch and process this value. But we should clarify one important fact: on the back-end and on the front-end static enums must have the same data set, otherwise this is an expected error. This case is easily circumvented in the second way of thinking by adding a few symbols:
component.ext
import { dataTypesKeys } from 'src/configs/data-types'
const func = type => dataTypesKeys[type] ?? 'Без значения' // look at me
func('BOOL') // Булево
5) This approach only works on static databut we get dynamic ones from our API.
6) So we created the only main source of truth and put it globally in the configs directory.