«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > GRASP в функциональном программировании на Javascript

GRASP в функциональном программировании на Javascript

Опубликовано 17 августа 2024 г.
Просматривать:736

GRASP in Javascript functional programming

В мире разработки программного обеспечения шаблоны проектирования служат проверенными временем решениями распространенных проблем.
Одним из менее обсуждаемых, но не менее важных наборов шаблонов проектирования является GRASP (Общие шаблоны распределения ответственности). Принципы GRASP часто коррелируют с принципами SOLID и другими шаблонами ООП-проектирования.
GRASP, или шаблоны программного обеспечения общего назначения ответственности, представляет собой набор руководящих принципов, направленных на назначение обязанностей классам и объектам в объектно-ориентированном проектировании. Как мы можем использовать эти шаблоны в нашей разработке на Javascript (Node.js)? Конечно, Javascript поддерживает классы, которые изначально созданы на основе прототипов, где мы можем применять GRASP аналогично тому, как мы это делаем в Java.
Однако, по моему мнению, шаблоны GRASP также можно применять и к функциональному программированию.

Что такое ГРАСП?

Девять шаблонов GRASP:

  1. Информационный эксперт
  2. Создатель
  3. Контроллер
  4. Низкая связь
  5. Высокая сплоченность
  6. Полиморфизм
  7. Чистая выдумка
  8. Косвенность
  9. Защищенные варианты

Информационный эксперт

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

// User management module
const createUser = (name, email) => ({ name, email });

const getUserEmail = (user) => user.email;

const updateUserEmail = (user, newEmail) => ({
  ...user,
  email: newEmail,
});

const user = createUser('John Doe', '[email protected]');
console.log(getUserEmail(user));  // '[email protected]'

const updatedUser = updateUserEmail(user, '[email protected]');
console.log(getUserEmail(updatedUser));  // '[email protected]'

Создатель

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

const createUser = (name, email) => ({ name, email });

Контроллер

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

// Example of express.js controller
const handleRequest = (req, res, userService) => {
  const user = userService.createUser(req.body.name, req.body.email);
  res.send(user);
};

Низкая связь

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

const sendEmail = (emailService, email) => emailService.send(email);

Высокая сплоченность

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

const createUser = (name, email) => ({ name, email });
const addUser = (users, user) => [...users, user];

const createAndAddUser = (users, name, email)=>{
  const user = createUser(name, email);
  return addUser(users, user)
}
// usage
const users = [
  { name: 'Alice', email: '[email protected]' },
  { name: 'Bob', email: '[email protected]' },
];

const newUsers = createAndAddUser(users, 'Charlie', '[email protected]');

Полиморфизм

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

const processPayment = (paymentMethod) => paymentMethod.process();

Чистое производство

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

const log = (message) => console.log(message);

Косвенность

Косвенность в функциональном программировании означает использование промежуточных функций для управления взаимодействием между различными частями системы. Хорошим примером в Node.js может быть шаблон промежуточного программного обеспечения.

const withNumberFilterMiddleware = (data) => data.filter(item => !isNaN(Number(item)));

Защищенные варианты

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

const processCreditCardPayment = (amount) => {
  console.log(`Processing credit card payment of ${amount}`);
  // Credit card payment logic
};

const processPayPalPayment = (amount) => {
  console.log(`Processing PayPal payment of ${amount}`);
  // PayPal payment logic
};

const processPayment = (paymentMethod, amount) => {
  paymentMethod(amount);
};

// Use different payment methods without changing the processPayment function
processPayment(processCreditCardPayment, 100);
processPayment(processPayPalPayment, 200);

Краткое содержание

Как видите, принципы GRASP коррелируют со многими известными шаблонами проектирования, а также с принципами SOLID. Высокая сплоченность почти равна принципу единой ответственности и так далее.
Эти принципы являются не только принципами ООП, но и общими принципами программирования хорошо спроектированного чистого кода, будь то его функциональное программирование или ООП.

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/ohanhaliuk/grasp-in-javascript-functional-programming-2jh6?1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить их.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3