← Назад к вопросам
Приведи пример использования паттернов программирования
1.8 Middle🔥 161 комментариев
#ООП и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры использования паттернов программирования в Flutter
Паттерны программирования — это проверенные решения для общих проблем. В Flutter используется множество паттернов. Рассмотрю самые важные и их практическое применение.
1. Builder Pattern
// Builder паттерн — создание сложных объектов пошагово
class UserBuilder {
String _name = '';
String _email = '';
int _age = 0;
String? _phone;
bool _isActive = true;
UserBuilder setName(String name) {
_name = name;
return this; // Для цепочки вызовов
}
UserBuilder setEmail(String email) {
_email = email;
return this;
}
UserBuilder setAge(int age) {
_age = age;
return this;
}
UserBuilder setPhone(String phone) {
_phone = phone;
return this;
}
UserBuilder setActive(bool isActive) {
_isActive = isActive;
return this;
}
User build() {
if (_name.isEmpty || _email.isEmpty) {
throw Exception('Name and email required');
}
return User(
name: _name,
email: _email,
age: _age,
phone: _phone,
isActive: _isActive,
);
}
}
class User {
final String name;
final String email;
final int age;
final String? phone;
final bool isActive;
User({
required this.name,
required this.email,
required this.age,
this.phone,
required this.isActive,
});
}
// Использование
void main() {
final user = UserBuilder()
.setName('John Doe')
.setEmail('john@example.com')
.setAge(30)
.setPhone('+1234567890')
.setActive(true)
.build();
print(user.name); // John Doe
}
2. Observer Pattern
// Observer паттерн — подписка на изменения
abstract class Observer {
void update(String event);
}
class EventBus {
final List<Observer> _observers = [];
void subscribe(Observer observer) {
_observers.add(observer);
}
void unsubscribe(Observer observer) {
_observers.remove(observer);
}
void notify(String event) {
for (final observer in _observers) {
observer.update(event);
}
}
}
class EmailNotifier extends Observer {
@override
void update(String event) {
print('Email: $event');
}
}
class LoggerObserver extends Observer {
@override
void update(String event) {
print('Log: $event');
}
}
// Использование
void main() {
final bus = EventBus();
final emailNotifier = EmailNotifier();
final logger = LoggerObserver();
bus.subscribe(emailNotifier);
bus.subscribe(logger);
bus.notify('User logged in');
// Output:
// Email: User logged in
// Log: User logged in
}
3. Strategy Pattern
// Strategy паттерн — различные алгоритмы
abstract class SortStrategy {
List<int> sort(List<int> numbers);
}
class BubbleSort implements SortStrategy {
@override
List<int> sort(List<int> numbers) {
final arr = List<int>.from(numbers);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
final temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
}
class QuickSort implements SortStrategy {
@override
List<int> sort(List<int> numbers) {
if (numbers.isEmpty) return [];
// Реализация quicksort
return numbers;
}
}
class Sorter {
final SortStrategy strategy;
Sorter(this.strategy);
List<int> sortNumbers(List<int> numbers) {
return strategy.sort(numbers);
}
}
// Использование
void main() {
final numbers = [5, 2, 8, 1, 9];
// Используем BubbleSort
final bubbleSorter = Sorter(BubbleSort());
print(bubbleSorter.sortNumbers(numbers));
// Меняем на QuickSort
final quickSorter = Sorter(QuickSort());
print(quickSorter.sortNumbers(numbers));
}
4. Decorator Pattern
// Decorator паттерн — добавление функционала
abstract class Coffee {
double getCost();
String getDescription();
}
class SimpleCoffee implements Coffee {
@override
double getCost() => 2.0;
@override
String getDescription() => 'Simple Coffee';
}
abstract class CoffeeDecorator implements Coffee {
final Coffee coffee;
CoffeeDecorator(this.coffee);
@override
double getCost() => coffee.getCost();
@override
String getDescription() => coffee.getDescription();
}
class MilkDecorator extends CoffeeDecorator {
MilkDecorator(Coffee coffee) : super(coffee);
@override
double getCost() => super.getCost() + 0.5;
@override
String getDescription() => '${super.getDescription()}, Milk';
}
class SugarDecorator extends CoffeeDecorator {
SugarDecorator(Coffee coffee) : super(coffee);
@override
double getCost() => super.getCost() + 0.2;
@override
String getDescription() => '${super.getDescription()}, Sugar';
}
// Использование
void main() {
Coffee coffee = SimpleCoffee();
print('${coffee.getDescription()}: \$${coffee.getCost()}');
coffee = MilkDecorator(coffee);
print('${coffee.getDescription()}: \$${coffee.getCost()}');
coffee = SugarDecorator(coffee);
print('${coffee.getDescription()}: \$${coffee.getCost()}');
// Output:
// Simple Coffee: $2.0
// Simple Coffee, Milk: $2.5
// Simple Coffee, Milk, Sugar: $2.7
}
5. Adapter Pattern
// Adapter паттерн — совместимость интерфейсов
// Старый интерфейс
class OldPaymentSystem {
void pay(double amount, String currency) {
print('Processing $currency $amount with old system');
}
}
// Новый интерфейс
abstract class NewPaymentGateway {
Future<bool> processPayment(PaymentRequest request);
}
class PaymentRequest {
final double amount;
final String currency;
final String cardToken;
PaymentRequest({
required this.amount,
required this.currency,
required this.cardToken,
});
}
// Adapter
class PaymentAdapter implements NewPaymentGateway {
final OldPaymentSystem _oldSystem;
PaymentAdapter(this._oldSystem);
@override
Future<bool> processPayment(PaymentRequest request) async {
_oldSystem.pay(request.amount, request.currency);
return true;
}
}
// Использование
void main() async {
final oldSystem = OldPaymentSystem();
final adapter = PaymentAdapter(oldSystem);
final request = PaymentRequest(
amount: 100.0,
currency: 'USD',
cardToken: 'token_123',
);
final result = await adapter.processPayment(request);
print('Payment successful: $result');
}
6. MVC Pattern в Flutter
// Model
class User {
final int id;
final String name;
final String email;
User({
required this.id,
required this.name,
required this.email,
});
}
// View
class UserListView extends StatelessWidget {
final List<User> users;
const UserListView({required this.users});
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text(user.name),
subtitle: Text(user.email),
);
},
);
}
}
// Controller
class UserController extends ChangeNotifier {
List<User> _users = [];
List<User> get users => _users;
Future<void> fetchUsers() async {
_users = [
User(id: 1, name: 'John', email: 'john@example.com'),
User(id: 2, name: 'Jane', email: 'jane@example.com'),
];
notifyListeners();
}
}
// Использование
class UserPage extends StatefulWidget {
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
final _controller = UserController();
@override
void initState() {
super.initState();
_controller.addListener(() => setState(() {}));
_controller.fetchUsers();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Users')),
body: UserListView(users: _controller.users),
);
}
}
7. Repository Pattern
// Repository паттерн — абстракция доступа к данным
abstract class UserRepository {
Future<User?> getUserById(int id);
Future<List<User>> getAllUsers();
Future<void> createUser(User user);
Future<void> updateUser(User user);
Future<void> deleteUser(int id);
}
class LocalUserRepository implements UserRepository {
final List<User> _cache = [];
@override
Future<User?> getUserById(int id) async {
return _cache.firstWhereOrNull((u) => u.id == id);
}
@override
Future<List<User>> getAllUsers() async => _cache;
@override
Future<void> createUser(User user) async {
_cache.add(user);
}
@override
Future<void> updateUser(User user) async {
// Обновить
}
@override
Future<void> deleteUser(int id) async {
_cache.removeWhere((u) => u.id == id);
}
}
class RemoteUserRepository implements UserRepository {
final ApiClient _api;
RemoteUserRepository(this._api);
@override
Future<User?> getUserById(int id) => _api.get('/users/$id');
@override
Future<List<User>> getAllUsers() => _api.get('/users');
@override
Future<void> createUser(User user) => _api.post('/users', user);
@override
Future<void> updateUser(User user) => _api.put('/users/${user.id}', user);
@override
Future<void> deleteUser(int id) => _api.delete('/users/$id');
}
// Использование
class UserService {
final UserRepository _repository;
UserService(this._repository);
Future<List<User>> loadUsers() => _repository.getAllUsers();
Future<void> saveUser(User user) => _repository.createUser(user);
}
8. BLoC Pattern (Popular in Flutter)
// BLoC = Business Logic Component
enum UserEvent { load, refresh }
enum UserState { initial, loading, loaded, error }
class UserBloc extends Bloc<UserEvent, UserState> {
final UserRepository _repository;
UserBloc(this._repository) : super(UserState.initial) {
on<UserEvent>((event, emit) async {
if (event == UserEvent.load || event == UserEvent.refresh) {
emit(UserState.loading);
try {
final users = await _repository.getAllUsers();
emit(UserState.loaded);
} catch (e) {
emit(UserState.error);
}
}
});
}
}
// Использование
class UserListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => UserBloc(repository),
child: BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state == UserState.loading) {
return CircularProgressIndicator();
}
if (state == UserState.loaded) {
return UserListView();
}
return Text('Error loading users');
},
),
);
}
}
Резюме
Основные паттерны в Flutter:
- Builder — создание сложных объектов
- Observer — подписка на события
- Strategy — разные алгоритмы
- Decorator — добавление функционала
- Adapter — совместимость интерфейсов
- MVC — разделение concerns
- Repository — абстракция доступа к данным
- BLoC — управление бизнес-логикой
Правило: Используй паттерны когда они решают реальную проблему, не усложняй код без необходимости!