← Назад к вопросам

Что такое абстракция?

1.0 Junior🔥 292 комментариев
#Dart#ООП и паттерны

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Абстракция

Абстракция — это принцип объектно-ориентированного программирования (ООП), который скрывает сложные детали реализации и предоставляет только необходимый интерфейс для использования. Абстракция позволяет работать с объектами на высоком уровне, не волнуясь о том, как они устроены внутри.

Суть абстракции

Это как использование автомобиля: вы не обязаны знать, как работает двигатель, трансмиссия и электрика. Вам нужно знать только:

  • Как завести машину
  • Как нажимать педали
  • Как рулить

Аналлогично в программировании: пользователь класса не должен знать о его внутренней реализации.

Абстракция через интерфейсы и классы

Без абстракции (ПЛОХО)

class User {
  String _name;
  String _email;
  String _passwordHash;
  
  User(this._name, this._email, this._passwordHash);
  
  // Клиент кода должен сам управлять паролем
  void setPassword(String password) {
    // Клиент должен помнить про хеширование
    _passwordHash = sha256.convert(password.codeUnits).toString();
  }
  
  bool checkPassword(String password) {
    // Клиент должен помнить про хеширование
    return _passwordHash == sha256.convert(password.codeUnits).toString();
  }
}

// Клиент кода
final user = User('John', 'john@example.com', 'some_hash');
user.setPassword('password123'); // Клиент знает о хешировании

С абстракцией (ХОРОШО)

abstract class AuthService {
  void setPassword(String password);
  bool verifyPassword(String password);
}

class User implements AuthService {
  String _name;
  String _email;
  late String _passwordHash;
  
  User(this._name, this._email);
  
  @override
  void setPassword(String password) {
    // Деталь реализации скрыта
    _passwordHash = _hashPassword(password);
  }
  
  @override
  bool verifyPassword(String password) {
    // Деталь реализации скрыта
    return _passwordHash == _hashPassword(password);
  }
  
  String _hashPassword(String password) {
    // Внутренняя реализация, её видит только класс
    return 'hashed_$password';
  }
}

// Клиент кода
final AuthService user = User('John', 'john@example.com');
user.setPassword('password123'); // Просто и понятно
user.verifyPassword('password123'); // Клиент не знает о хешировании

Абстрактные классы в Dart

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

// Абстрактный класс
abstract class Shape {
  // Абстрактный метод (без реализации)
  double getArea();
  
  double getPerimeter();
  
  // Конкретный метод (с реализацией)
  void describe() {
    print('Площадь: ${getArea()}');
    print('Периметр: ${getPerimeter()}');
  }
}

// Конкретные реализации
class Circle implements Shape {
  final double radius;
  
  Circle(this.radius);
  
  @override
  double getArea() => 3.14 * radius * radius;
  
  @override
  double getPerimeter() => 2 * 3.14 * radius;
}

class Rectangle implements Shape {
  final double width;
  final double height;
  
  Rectangle(this.width, this.height);
  
  @override
  double getArea() => width * height;
  
  @override
  double getPerimeter() => 2 * (width + height);
}

// Использование
final Shape circle = Circle(5);
final Shape rect = Rectangle(4, 6);

circle.describe(); // Площадь и периметр для круга
rect.describe();   // Площадь и периметр для прямоугольника

Абстракция в Flutter

Пример: Система платежей

// Абстракция платежной системы
abstract class PaymentProcessor {
  Future<bool> processPayment(double amount, String cardToken);
  Future<bool> refund(String transactionId);
}

// Конкретная реализация для Stripe
class StripePaymentProcessor implements PaymentProcessor {
  final String apiKey;
  
  StripePaymentProcessor({required this.apiKey});
  
  @override
  Future<bool> processPayment(double amount, String cardToken) async {
    // Специфичная логика Stripe
    print('Processing $amount with Stripe');
    // Вызов Stripe API
    return true;
  }
  
  @override
  Future<bool> refund(String transactionId) async {
    print('Refunding transaction $transactionId with Stripe');
    return true;
  }
}

// Конкретная реализация для PayPal
class PayPalPaymentProcessor implements PaymentProcessor {
  final String apiKey;
  
  PayPalPaymentProcessor({required this.apiKey});
  
  @override
  Future<bool> processPayment(double amount, String cardToken) async {
    // Специфичная логика PayPal
    print('Processing $amount with PayPal');
    return true;
  }
  
  @override
  Future<bool> refund(String transactionId) async {
    print('Refunding transaction $transactionId with PayPal');
    return true;
  }
}

// Бизнес-логика (не знает о деталях платежа)
class CheckoutService {
  final PaymentProcessor processor;
  
  CheckoutService({required this.processor});
  
  Future<bool> checkout(double amount, String cardToken) async {
    return await processor.processPayment(amount, cardToken);
  }
}

// Использование
final stripe = StripePaymentProcessor(apiKey: 'stripe_key');
final checkout = CheckoutService(processor: stripe);
await checkout.checkout(99.99, 'token_123');

// Переключение на PayPal
final paypal = PayPalPaymentProcessor(apiKey: 'paypal_key');
final checkout2 = CheckoutService(processor: paypal);
await checkout2.checkout(99.99, 'token_456');

Преимущества абстракции

  1. Простота — клиент использует простой интерфейс
  2. Гибкость — легко менять реализацию
  3. Поддерживаемость — изменения внутри класса не влияют на клиентов
  4. Тестируемость — легко создавать моки для тестов
  5. Масштабируемость — расширение кода без изменения существующего

Абстракция vs Инкапсуляция

  • Абстракция — скрывает сложность (ЧТО)
  • Инкапсуляция — скрывает данные (КАК)

Абстракция — фундаментальный принцип SOLID, который помогает создавать чистый и масштабируемый код.