-
Notifications
You must be signed in to change notification settings - Fork 1
Coding Standards
This document provides coding standards and guidelines to ensure code quality, maintainability, and consistency for projects using Flutter and Firebase. Adhering to these standards will help in understanding and maintaining the codebase.
Write clear, readable, and maintainable code. Follow DRY (Don't Repeat Yourself) and KISS (Keep It Simple, Stupid) principles. Adhere to the Flutter and Dart best practices and Firebase security rules.
Use meaningful and descriptive names.
Use camelCase for variable names.
// Good
int userAge;
// Bad
int ua;
Use descriptive names.
Use camelCase for function names.
// Good
void fetchUserData() { }
// Bad
void fetch() { }
Use PascalCase for class names.
// Good
class UserProfile { }
// Bad
class userprofile { }
Use PascalCase for constant names.
// Good
const int MaxUsers = 100;
// Bad
const int maxusers = 100;
We will use Flutter's built-in linter tool to lint, ensuring high quality code. The linter we are using is well-suited for the task, being that it is provided by the Flutter Development team. We can configure the analysis options in the analysis_options.yaml file to enforce specific rules and guidelines. In our project we did not have to alter any specific rules for the linter.
Use 2 spaces per indentation level.
void main() {
if (true) {
print("Indented");
}
}
Limit lines to 80 characters. Use line breaks for longer lines.
// Good
final message = "This is a long message "
"that is split into multiple lines.";
// Bad
final message = "This is a very long message that exceeds the limit of 80 characters.";
Use spaces around operators and after commas.
// Good
int result = a + b;
// Bad
int result=a+b;
Structure widgets hierarchically for readability.
Use const constructors where possible to optimize performance.
// Good
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: Text("Hello, World!"),
),
);
}
// Bad
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text("Hello, World!")));
}
.dart_tool/ .github/ android/ assets/ build/ ios/ lib/ ├── components/ ├── models/ ├── pages/ | ├── customize_page.dart | ├── customize_profile_page.dart | ├── game_library_page.dart │ ├── home_page.dart │ ├── login_page.dart │ ├── profile_page.dart | └── sign_up.dart ├── services/ │ └── auth_service.dart ├── theme/ │ ├── theme_provider.dart │ └── themes.dart ├── main.dart └── firebase_options.dart linux/ macos/ test/ web/ windows/ .env .flutter-pluggins .flutter-pluggins-dependencies .gitignore .metadata analysis_options.yaml firebase.json pubspec.lock pubspec.yaml README.md
Use inline comments sparingly and only for complex or non-obvious code.
int result = calculate(); // Calculate the final result
Use block comments to explain sections of code.
/*
* This block of code fetches user data
* and handles authentication.
*/
Write Dartdoc comments for public classes and functions.
/// Adds two numbers and returns the result.
///
/// The parameters [a] and [b] are the numbers to be added.
int add(int a, int b) {
return a + b;
}
Use appropriate state management techniques based on the complexity of the app (e.g., Provider, Riverpod, Bloc, etc.).
Keep business logic separate from UI code.
// Example using Provider
class CounterModel extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
Use try-catch blocks to handle exceptions gracefully.
Avoid using exceptions for control flow.
// Good
try {
final user = await fetchUser();
} catch (e) {
print('Error fetching user: $e');
}
// Bad
if (errorOccurred) {
throw Exception("Error occurred");
}
Secure Firestore rules and Firebase functions.
Use Firestore transactions where data consistency is crucial.
Handle asynchronous operations correctly.
// Good Firestore query
FirebaseFirestore.instance
.collection('users')
.where('isActive', isEqualTo: true)
.get()
.then((snapshot) {
// Handle snapshot
}).catchError((error) {
// Handle error
});
Write unit tests for business logic.
Use widget tests for UI components.
Follow TDD (Test-Driven Development) principles when possible.
void main() {
test('Counter increments', () {
final counter = CounterModel();
counter.increment();
expect(counter.counter, 1);
});
}
Commit code regularly with meaningful commit messages.
Use branching strategies for feature development, bug fixes, and releases.
// Good commit message
git commit -m "Implement user authentication with Firebase"
// Bad commit message
git commit -m "Fix"
Conduct regular code reviews.
Provide constructive feedback and focus on the code, not the person.
Effective Dart
Flutter Documentation
Firebase Documentation