Что такое DTO (Data Transfer Object) в контексте Flutter-приложения?

«Что такое DTO (Data Transfer Object) в контексте Flutter-приложения?» — вопрос из категории Архитектура, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

DTO (Data Transfer Object) — это простой объект, предназначенный исключительно для передачи данных между различными слоями приложения или между клиентом и сервером. В моих Flutter-проектах DTO обычно используются для десериализации JSON-ответов от API.

Типичная реализация DTO во Flutter/Dart:

import 'dart:convert';

// DTO для пользовательских данных с API
class UserDto {
  final String id;
  final String email;
  final String firstName;
  final String lastName;
  final DateTime createdAt;

  UserDto({
    required this.id,
    required this.email,
    required this.firstName,
    required this.lastName,
    required this.createdAt,
  });

  // Фабричный конструктор для десериализации JSON
  factory UserDto.fromJson(Map<String, dynamic> json) {
    return UserDto(
      id: json['id'] as String,
      email: json['email'] as String,
      firstName: json['first_name'] as String,
      lastName: json['last_name'] as String,
      createdAt: DateTime.parse(json['created_at'] as String),
    );
  }

  // Метод для сериализации в JSON
  Map<String, dynamic> toJson() => {
    'id': id,
    'email': email,
    'first_name': firstName,
    'last_name': lastName,
    'created_at': createdAt.toIso8601String(),
  };

  // Преобразование DTO в доменную модель
  User toDomain() {
    return User(
      id: UserId(id),
      email: Email(email),
      fullName: '$firstName $lastName',
      registrationDate: createdAt,
    );
  }
}

// Пример использования с http-пакетом
Future<UserDto> fetchUser(String userId) async {
  final response = await http.get(
    Uri.parse('https://api.example.com/users/$userId'),
  );

  if (response.statusCode == 200) {
    final jsonData = jsonDecode(response.body) as Map<String, dynamic>;
    return UserDto.fromJson(jsonData);
  } else {
    throw Exception('Failed to load user');
  }
}

Ключевые характеристики DTO в моей практике:

  • Содержат только данные и методы преобразования
  • Обычно immutable (все поля final)
  • Включают методы fromJson/toJson для работы с API
  • Отделены от бизнес-логики и UI-логики
  • Могут отличаться от доменных моделей структурой полей