Member-only story
Implementing SOLID Principles in Flutter Applications
The SOLID principles are fundamental guidelines in object-oriented programming that help create maintainable and scalable software. Let’s explore how to apply these principles in Flutter development.
1. Single Responsibility Principle (SRP)
This principle states that a class should have only one reason to change. In Flutter, we can apply this to widgets, services, and models.
Bad Practice ❌:
class UserWidget extends StatelessWidget {
final User user;
UserWidget({required this.user});
Future<void> saveUser() async {
// Database operations
await DatabaseHelper.instance.insertUser(user);
// API calls
await ApiService.updateUser(user);
// Local storage
await SharedPreferences.getInstance()
.setString('user_data', json.encode(user.toJson()));
}
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: [
Text(user.name),
Text(user.email),
ElevatedButton(
onPressed: saveUser,
child: Text('Save User'),
),
],
),
);
}
}Good Practice ✅:
// User Repository
class UserRepository {
Future<void> saveUser(User user) async {
await DatabaseHelper.instance.insertUser(user);
await ApiService.updateUser(user);
await _saveToLocalStorage(user);
}
Future<void> _saveToLocalStorage(User user) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('user_data', json.encode(user.toJson()));
}
}
// User Widget
class UserWidget extends StatelessWidget {
final User user;
final UserRepository userRepository;
UserWidget({
required this.user,
required this.userRepository,
});
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: [
UserInfoDisplay(user: user),
UserActionButtons(
onSave: () => userRepository.saveUser(user),
),
],
),
);
}
}2. Open/Closed Principle (OCP)
Classes should be open for extension but closed for modification.