Множественный if рефакторинг
У меня есть эта функция, с двумя if
где я хочу найти пользователя в зависимости от того, какой буквенно-цифровой код я получаю. Как я могу рефакторинг этого с Sanctuary-JS?
//const code = '0011223344';
const code = 'aabbc';
const isNumberCode = code => !!/^[0-9]{10}$/.exec(code);
const isLiteralCode = code => !!/^[A-Za-z]{5}$/.exec(code);
const findUser = (criteria) => {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('user object');
}, 300);
});
}
async function handler(code) {
if (isNumberCode(code)) {
const user = await findUser({id: code});
return user;
}
if (isLiteralCode(code)) {
const user = await findUser({identifier: code});
return user;
}
return 'not found';
}
async function run() {
const user = await handler(code);
console.log(user)
}
run();
Я не могу понять, как я должен обрабатывать три разных типа: числовой код, буквенный код и не найденный код.
-- ОБНОВИТЬ
Вот мое функциональное решение (я так думаю):
const Code = x => ({
chain: f => f(x),
fold: (e, a, f) => e(x)
});
const ErrorCode = x => ({
fold: (e, a, f) => e(x),
findLabel: f => ErrorCode(x)
});
const PromiseToCode = promise => ({
fold: (e, a, f) => promise.then(x => x.fold(e, a, f))
});
const NumberCode = x => ({
fold: (e, a, f) => a(x),
findLabel: f => PromiseToCode(f(x, {activationCode: x}, NumberCode))
});
const LiteralCode = x => ({
fold: (e, a, f) => f(x),
findLabel: f => PromiseToCode(f(x, {finderCode: x}, LiteralCode))
});
const checkTypeOfCode = code => {
if (isNumberCode(code)) {
return NumberCode(code);
}
if (isLiteralCode(code)) {
return LiteralCode(code);
}
return ErrorCode(code);
};
const find = async (code, criteria, type) => {
const user = findUser();
if (!user) {
return ErrorCode(code);
}
return type(user);
};
const handler2 = (code) =>
Code(code)
.chain(checkTypeOfCode)
.findLabel(find)
.fold(
e => 'not found',
a => 'user object find by id',
l => 'user object find by identifier'
)
handler2(code).then(console.log);
Но я не знаю, хороший ли это код. Также я спрашиваю про sanctuary-js, потому что считаю, что весь этот объект не хороший способ программирования.
2 ответа
Вы можете создать enum для нескольких типов ввода и использовать оператор switch, как показано ниже.
// Enum for search-parameters
var ParameterTypes =
{
NUMBER :1 ,
LITERAL:2 ,
OTHER : 3
}
function getParameterType()
{
//responsible to get search-parameter
return isNumberCode(code) ? ParameterTypes.NUMBER :
( isLiteralCode(code) ? ParameterTypes.LITERAL : ParameterTypes.OTHER);
}
async function handler(code)
{
//responsible to search user
var user;
switch(getParameterType())
{
case ParameterTypes.NUMBER :
user = await findUser({id: code});
//console.log('number');
break;
case ParameterTypes.LITERAL :
user = await findUser({identifier: code});
//console.log('literal');
break;
case ParameterTypes.OTHER :
user = 'not found';
//console.log('other');
break;
}
return user;
}
Поскольку вы ищете более функциональную реструктуризацию, вы можете попробовать это:
Разделите ваш код на меньшие, более независимые разделы:
findUser
: Эта функция отвечает заUserObject
или жеNot found
,- Создать функцию
getCriteria
, что будет иметь всю логику, чтобыisNumberCode
или жеisLiteralCode
и т.д. Это вернет объект критерия илиundefined
, handler
должен нести ответственность за получение критериев, и на основе этого возвращенияfindUser
ответ. Здесь можно сохранить любой код очистки, но это хаб-функция, которая вызывает различные функции и возвращает результат. У него должна быть минимальная бизнес-логика.
//const code = '0011223344';
const code = 'aabbc';
const isNumberCode = code => !!/^[0-9]{10}$/.exec(code);
const isLiteralCode = code => !!/^[A-Za-z]{5}$/.exec(code);
const findUser = (criteria) => {
return new Promise(function(resolve, reject) {
if (!criteria) resolve('not found')
setTimeout(function() {
resolve('user object');
}, 300);
});
}
function getCriteria(code) {
if (isNumberCode(code)) {
return { id: code };
}
if (isLiteralCode(code)) {
return { identifier: code }
}
}
async function handler(code) {
const user = await findUser(getCriteria(code))
return user;
}
async function run() {
const user = await handler(code);
console.log(user)
}
run();