Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие знаешь паттерны ООП
Паттерны ООП — это проверенные решения для типичных проблем в объектно-ориентированном программировании. В Flutter они применяются постоянно.
Основные принципы ООП
1. Инкапсуляция (Encapsulation)
Скрывание внутренней реализации, предоставление публичного интерфейса.
class BankAccount {
double _balance = 0; // Приватное поле
// Публичный интерфейс
double get balance => _balance;
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
}
}
bool withdraw(double amount) {
if (amount > 0 && amount <= _balance) {
_balance -= amount;
return true;
}
return false;
}
}
2. Наследование (Inheritance)
Повторное использование кода через иерархию классов.
class Animal {
void sound() {
print('Животное издаёт звук');
}
}
class Dog extends Animal {
@override
void sound() {
print('Собака лает');
}
}
class Cat extends Animal {
@override
void sound() {
print('Кот мяукает');
}
}
3. Полиморфизм (Polymorphism)
Способность объектов принимать много форм.
List<Animal> animals = [Dog(), Cat(), Animal()];
for (var animal in animals) {
animal.sound(); // Вызовется переопределённый метод каждого класса
}
// Вывод:
// Собака лает
// Кот мяукает
// Животное издаёт звук
4. Абстракция (Abstraction)
Скрывание сложности, показ только необходимого интерфейса.
abstract class Shape {
double getArea();
double 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, height;
Rectangle(this.width, this.height);
@override
double getArea() => width * height;
@override
double getPerimeter() => 2 * (width + height);
}
SOLID принципы
S — Single Responsibility
Один класс = одна ответственность.
// ❌ Плохо — класс делает слишком много
class User {
String name;
String email;
void save() {} // БД операция
void sendEmail() {} // Email операция
void validateEmail() {} // Валидация
}
// ✅ Хорошо — разделение ответственности
class User {
String name;
String email;
}
class UserRepository {
void save(User user) {}
}
class EmailService {
void send(String email, String message) {}
}
class EmailValidator {
bool isValid(String email) => email.contains('@');
}
O — Open/Closed
Открыт для расширения, закрыт для модификации.
// ❌ Плохо — нужно модифицировать класс
class PaymentProcessor {
void process(String type, double amount) {
if (type == 'credit_card') {
print('Обработка кредитной карты');
} else if (type == 'paypal') {
print('Обработка PayPal');
}
}
}
// ✅ Хорошо — можно расширять без модификации
abstract class PaymentMethod {
void process(double amount);
}
class CreditCard implements PaymentMethod {
@override
void process(double amount) {
print('Обработка кредитной карты: $amount');
}
}
class PayPal implements PaymentMethod {
@override
void process(double amount) {
print('Обработка PayPal: $amount');
}
}
class PaymentProcessor {
void process(PaymentMethod method, double amount) {
method.process(amount);
}
}
L — Liskov Substitution
Подтипы должны быть заменяемы базовыми типами.
// ✅ Правильное наследование
abstract class Bird {
void eat();
}
class Sparrow extends Bird {
@override
void eat() => print('Воробей клюёт зёрна');
}
class Eagle extends Bird {
@override
void eat() => print('Орёл ест добычу');
}
// Можно заменять
Bird bird1 = Sparrow();
Bird bird2 = Eagle();
void feedBird(Bird bird) {
bird.eat(); // Работает для любой птицы
}
I — Interface Segregation
Много маленьких интерфейсов лучше одного большого.
// ❌ Плохо — большой интерфейс
abstract class Worker {
void work();
void eat();
void sleep();
}
// ✅ Хорошо — разделённые интерфейсы
abstract class Workable {
void work();
}
abstract class Eatable {
void eat();
}
abstract class Sleepable {
void sleep();
}
class Robot implements Workable {
@override
void work() => print('Робот работает');
// Не нужно реализовывать eat() и sleep()
}
class Human implements Workable, Eatable, Sleepable {
@override
void work() => print('Человек работает');
@override
void eat() => print('Человек ест');
@override
void sleep() => print('Человек спит');
}
D — Dependency Inversion
Зависимости от абстракций, а не от конкретных реализаций.
// ❌ Плохо — зависимость от конкретной реализации
class UserService {
final SqliteDatabase db = SqliteDatabase();
void save(User user) {
db.insert(user);
}
}
// ✅ Хорошо — зависимость от интерфейса
abstract class Database {
void insert(User user);
void update(User user);
void delete(String id);
}
class SqliteDatabase implements Database {
@override
void insert(User user) => print('SQLite insert');
@override
void update(User user) => print('SQLite update');
@override
void delete(String id) => print('SQLite delete');
}
class FirebaseDatabase implements Database {
@override
void insert(User user) => print('Firebase insert');
@override
void update(User user) => print('Firebase update');
@override
void delete(String id) => print('Firebase delete');
}
class UserService {
final Database db;
UserService(this.db); // Dependency injection
void save(User user) {
db.insert(user);
}
}
// Можно подставить любую БД
final service1 = UserService(SqliteDatabase());
final service2 = UserService(FirebaseDatabase());
Паттерны проектирования
Creational (Порождающие)
Singleton — одна единственная инстанция
class Logger {
static final Logger _instance = Logger._internal();
factory Logger() {
return _instance;
}
Logger._internal();
void log(String message) => print('[LOG] $message');
}
final logger1 = Logger();
final logger2 = Logger();
print(logger1 == logger2); // true
Factory — создание объектов через фабрику
abstract class Shape {
factory Shape(String type) {
if (type == 'circle') return Circle();
if (type == 'square') return Square();
throw UnknownShapeException();
}
void draw();
}
class Circle implements Shape {
@override
void draw() => print('Рисую круг');
}
class Square implements Shape {
@override
void draw() => print('Рисую квадрат');
}
// Использование
Shape shape = Shape('circle');
shape.draw();
Structural (Структурные)
Adapter — подстраивание интерфейсов
abstract class Target {
void request();
}
class Adaptee {
void specificRequest() => print('Специфичный запрос');
}
class Adapter extends Target {
final Adaptee adaptee = Adaptee();
@override
void request() {
adaptee.specificRequest();
}
}
Behavioral (Поведенческие)
Observer — реагирование на изменения
abstract class Observer {
void update(String event);
}
class Subject {
final List<Observer> _observers = [];
void attach(Observer observer) {
_observers.add(observer);
}
void notify(String event) {
for (var observer in _observers) {
observer.update(event);
}
}
}
class ConcreteObserver extends Observer {
@override
void update(String event) {
print('Получил событие: $event');
}
}
Strategy — стратегии сортировки/обработки
abstract class SortStrategy {
List<int> sort(List<int> list);
}
class BubbleSort implements SortStrategy {
@override
List<int> sort(List<int> list) {
// Пузырёк
return list;
}
}
class QuickSort implements SortStrategy {
@override
List<int> sort(List<int> list) {
// Быстрая сортировка
return list;
}
}
class Sorter {
SortStrategy strategy;
Sorter(this.strategy);
List<int> sort(List<int> list) => strategy.sort(list);
}
Паттерны ООП — это язык общения между разработчиками. Их знание критично для написания поддерживаемого и масштабируемого кода.