Что такое GRASP и как применять эти принципы в Node.js разработке?

«Что такое GRASP и как применять эти принципы в Node.js разработке?» — вопрос из категории Паттерны, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

GRASP (General Responsibility Assignment Software Patterns) — это набор принципов для распределения ответственностей в объектно-ориентированном дизайне. В контексте Node.js с его модульной архитектурой, эти принципы помогают создавать поддерживаемый код даже без классических классов.

Применение GRASP в Node.js проектах:

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

    // Сервисный класс, владеющий логикой работы с заказами
    class OrderService {
    constructor(orderRepository) {
    this.orderRepository = orderRepository;
    }
    
    // Этот класс знает как вычислять общую стоимость
    async calculateTotal(orderId) {
    const order = await this.orderRepository.findById(orderId);
    return order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    }
    }
  2. Создатель:

    // Фабрика создает сложные объекты
    class LoggerFactory {
    static create(config) {
    const transports = [
      new transports.File({ filename: config.filePath }),
      new transports.Console()
    ];
    return new winston.createLogger({ transports });
    }
    }
  3. Контроллер:

    // Express контроллер обрабатывает HTTP запросы
    class UserController {
    async createUser(req, res) {
    try {
      const userData = req.body;
      const user = await this.userService.create(userData);
      res.status(201).json(user);
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
    }
    }
  4. Низкая связанность: Достигаю через Dependency Injection:

    
    // Вместо жесткой зависимости
    const paymentService = new PaymentService();

// Использую DI class OrderProcessor { constructor(paymentService, notificationService) { this.paymentService = paymentService; this.notificationService = notificationService; } }


5. **Высокая связность:** Группирую связанные функции в модулях:
```javascript
// auth-module.js
const validateToken = (token) => { /* ... */ };
const generateToken = (user) => { /* ... */ };
const hashPassword = (password) => { /* ... */ };

module.exports = { validateToken, generateToken, hashPassword };

В моих Node.js проектах эти принципы помогают создавать архитектуру, которую легко тестировать и расширять.