Skip to content

Best Coding Practice to Follow in Oceanmtech

Basic Rules

Common Rules

  • Kyarey setState use nathi karavanu always proper state managment use karvanu che.

  • State managment mate bloc(preferred) or provider bemathi aek j use karvanu rehshe.

  • Never use getx for state managment.

    • Disadvantages: (Ref: Medium)
      • Getx Provide Simplicity
      • GetX force to replacing Flutter
      • GetX tends to use anti-patterns
      • GetX tries to do everything
      • The level of documentation for GetX needs improvement.
      • The Unusual Number of API Elements in GetX.
  • Follow proper project architecture(MVC(Medium Project) or MVVM(Large Project))

  • Official Documentation Read karvanu aavdvu jove and ae must required skills che.

  • Effective Dart Programming Writing Style: 

    • Saro code write karvo and ae sari code pratice che and most important points che.
    • Consistent naming, ordering and format maintain karvathi ae code no look maintain thay shake che.
    • powerful pattern-matching hardware mate saru pade ke pattern match kari ne aapane suggestion provide kari aape (AI - Github Copilot)
    • and jo consistent code style hoy aakha dart na ecosystem mate to batha mate easier reshe ke aemathi shikhva mate and aek bija na code ma contributation karva mate.
    • and Oceanmtech aa code nu structure maintain karvu ae mandotory che je ne aapde universal code structure na rules par thi j aapde define karel che.
    • Aapde official dart language ni guide ne follow karvanu che:
    • Dart Programming Writing Rules (Read & Implement karvanu che)
  • OceanMTech na aek pan flutter developer ne jyare code write karta hoy tyare keyboard same jovu na padvu jove aena mate typing speed mate ni daily pratice karvani che and biju keyabord and mouse ni click fast action ma perform thay ae mandatory che.

  • Jyare code write karo cho aena file name and file location always yad rakhvana and aej rite function name variable name ae pan yad rakhvana and aena name pan function na according j lakhvana jenathi jyare ae module nu logic update thay tyare direct file name par thi ae file par jay shakay because jyare projects ma 1000 files hoy tyare manually find karvi ae time consuming process che.

Follow the Dart Style Guide

“Follow the Dart Style Guide” is a fundamental best practice in Dart and Flutter development. Dart, the programming language used for Flutter, has an official style guide that provides a set of conventions and guidelines for writing clean, consistent, and readable Dart code. Adhering to this style guide helps maintain code quality, improves codebase readability, and promotes consistency in coding practices across teams and projects.

Here’s a breakdown of why it’s essential to follow the Dart Style Guide and how to do so effectively:

Why Follow the Dart Style Guide:

  1. Consistency: Consistency in code style makes your codebase more predictable and easier to understand for both you and other developers who may work on the project.

  2. Readability: A consistent style enhances code readability by ensuring that code elements like variable names, formatting, and indentation follow a common pattern.

  3. Collaboration: When working on team projects, following a style guide ensures that all team members write code in a consistent manner, reducing friction during code reviews and collaboration.

  4. Maintainability: A well-structured and consistently styled codebase is easier to maintain and refactor. It reduces the likelihood of introducing new bugs during code changes.

  5. Scalability: As your Flutter project grows, adhering to a style guide becomes increasingly important. It helps manage complexity and ensures that your code remains manageable and extendable.

How to Follow the Dart Style Guide Effectively:

  1. Read the Official Dart Style Guide:
    - Familiarize yourself with the official Dart Style Guide, which is available at dart.dev/guides/style.
    - Pay attention to the conventions and recommendations for naming conventions, code formatting, and coding practices.

  2. Configure Your IDE/Editor:
    - Configure your development environment, including IDEs like Visual Studio Code, IntelliJ IDEA, or Android Studio, to automatically apply Dart’s formatting rules. The Dart SDK comes with a tool called dartfmt that helps format your code to comply with the style guide.

  3. Use Linters:
    - Consider using linters like dartanalyzer to perform static code analysis. Linters can identify code style violations and potential issues in your code.
    - Popular linters include pedantic, which enforces a strict adherence to the Dart Style Guide, and lint, which allows you to customize linting rules.

  4. Enable Lint Rules:
    - If you choose to use linters, enable and configure lint rules in your Dart project. You can do this by adding a .analysis_options file to your project’s root directory.

  5. Naming Conventions:
    - Follow Dart’s naming conventions for variables, functions, classes, and constants. Use lowerCamelCase for variable and function names, and UpperCamelCase for class names.

  6. Code Formatting:
    - Ensure that your code is formatted consistently. Use dartfmt or the built-in formatting features of your IDE to automatically apply formatting rules.

  7. Documentation Comments:
    - Include documentation comments (doc comments) for public APIs, classes, functions, and methods, following the conventions outlined in the style guide.

  8. Imports:
    - Organize import statements alphabetically and separate them into three groups: Dart imports, package imports, and local imports.

  9. Whitespace and Indentation:
    - Follow the recommended rules for whitespace, indentation, line lengths, and line breaks as outlined in the style guide.

  10. Code Structure:

    • Organize your code logically, breaking it into functions, classes, and libraries that have clear responsibilities and interfaces.
  11. Avoidance of Deprecated Features:

    • Stay updated with changes in Dart and Flutter and avoid using deprecated features and libraries. Refer to official documentation and release notes for updates.
  12. Regular Code Reviews:

    • Conduct regular code reviews within your team to ensure that the style guide is consistently followed. Code reviews are an opportunity to catch and correct style violations early.

By following the Dart Style Guide, you contribute to writing clean, consistent, and maintainable Dart and Flutter code. This adherence to best practices enhances code quality, fosters collaboration, and facilitates long-term project sustainability.

Use Descriptive Variable and Function Names

  • koi pan variables, functions, classes and widget na name descriptive choose karvana reshe, je aapane code vadhu samajavama and bija pan easy way ma samji shake and in future aapde aa project par return work start karvi to samajava mate easy reshe. so single-letter or cryptic variable names ne avoid karvu jaruri che, nichenu exaple refer karvu more details mate.

More in details:

  • “Use Descriptive Variable and Function Names” is a fundamental coding practice that involves choosing meaningful and informative names for variables, functions, methods, classes, and other identifiers in your code. The goal is to make your code more readable, self-explanatory, and maintainable by conveying the purpose and functionality of these elements through their names. This practice is crucial in Dart and Flutter development, as it enhances code understanding and collaboration. Here’s why it’s important and how to implement it effectively:

Why Use Descriptive Names:

  1. Code Readability: Clear and descriptive names make your code more readable and easier to understand for both yourself and other developers who may work on the project.

  2. Intent Clarification: Well-chosen names help convey the intent and purpose of variables, functions, and classes, reducing the need for extensive comments.

  3. Documentation Reduction: Descriptive names can replace or reduce the need for comments, as they provide self-documentation by describing what the code does.

  4. Maintenance: During maintenance or debugging, descriptive names can significantly reduce the time it takes to understand the code and locate potential issues.

  5. Collaboration: When working on a team, using descriptive names ensures that team members can understand and collaborate on code more effectively.

How to Use Descriptive Names Effectively:

  1. Choose Meaningful Names:
    - Select names that accurately represent the purpose and role of the variable, function, class, or method.
    - Avoid generic or cryptic names like x, temp, or foo.

  2. Use Clear and Understandable Language:
    - Use words from the problem domain or domain-specific terminology to name your identifiers.
    - Avoid abbreviations or acronyms that may not be universally understood unless they are well-known and widely accepted in your domain.

  3. Be Explicit:
    - Be explicit in your naming. A longer, descriptive name is often better than a shorter, ambiguous one. For example, use calculateTotalPrice instead of calc or total.

  4. Follow Naming Conventions:
    - Adhere to naming conventions and conventions outlined in the Dart Style Guide. For example, use lowerCamelCase for variables and function names, and UpperCamelCase for class names.

  5. Use Nouns for Variables and Constants:
    - Variable names should generally be nouns or noun phrases that describe what the variable represents. For example, userProfile, productList, or invoiceTotal.

  6. Use Verbs for Functions and Methods:
    - Function and method names should generally be verbs or verb phrases that describe what action they perform. For example, calculateTotalPrice(), fetchUserData(), or validateEmail().

  7. Avoid Overly Generic Names:
    - Avoid using names like data, result, or value without additional context. Provide context that clarifies what the data represents.

  8. Avoid Magic Numbers and Strings:
    - Replace magic numbers and strings in your code with well-named constants. For instance, replace const int maxAttempts = 3 instead of const int 3 when limiting attempts.

  9. Refactor as Needed:
    - If you find that an existing name is no longer descriptive due to code changes, don’t hesitate to refactor and choose a more appropriate name.

  10. Use Consistent Naming Styles:

    • Maintain consistency in naming styles throughout your codebase. Consistency makes the code more predictable and easier to navigate.
  11. Self-Explanatory Code:

    • Strive to make your code as self-explanatory as possible through the use of descriptive names. Minimize the need for comments by making the code’s intent evident in the names themselves.

Example

Here’s an example of code with descriptive names:

// Descriptive variable names
String userName = 'john_doe';
int itemCount = 10;
bool isLoggedIn = false;

// Descriptive function names
double calculateTotalPrice(double itemPrice, int quantity) {
  return itemPrice * quantity;
}

List<User> fetchActiveUsers() {
  // Implementation
}

By consistently using descriptive names, you enhance the clarity and maintainability of your Dart and Flutter code. This practice promotes better collaboration among developers, reduces the risk of misunderstandings, and ultimately leads to more robust and maintainable codebases.

Organize Code into Small Functions and Classes

  • Je pan code write karo ae small, reusable function and classes ma hovo jaruri che because function find karva ae more easy che instead code find karvo, so aa pratice aek code ne readability and maintainability banavi aape che, and flutter ma widgets ae aek good example che jema aa pratice follow thayeli che.

More in Details:

  • “Organize Code into Small Functions and Classes” is a best practice in software development, including Dart and Flutter development, that involves breaking down your code into smaller, more focused functions and classes. The goal is to improve code readability, maintainability, and reusability while reducing complexity. This practice aligns with the principles of modular programming and the Single Responsibility Principle (SRP) from SOLID design principles. Here’s why it’s important and how to implement it effectively:

Why Organize Code into Small Functions and Classes:

  1. Readability: Smaller functions and classes are easier to read and understand. They allow developers to focus on one specific task or responsibility at a time.

  2. Maintainability: Smaller code units are easier to maintain and debug. When a bug occurs or a change is needed, it’s quicker and more straightforward to locate the relevant code.

  3. Reusability: Well-structured, small functions and classes can be reused in different parts of your application or in other projects, reducing duplication of code.

  4. Testing: Smaller functions are easier to test. You can write unit tests to verify the behavior of individual functions or methods, improving code reliability.

  5. Scalability: As your Flutter project grows, organizing code into smaller units helps manage complexity and prevents your codebase from becoming unwieldy and difficult to manage.

How to Organize Code into Small Functions and Classes Effectively:

  1. Single Responsibility Principle (SRP):
    - Follow the SRP, which states that a function or class should have only one reason to change. If a function or class has multiple responsibilities, consider breaking it into smaller, more focused units.

  2. Descriptive Names:
    - Choose clear, descriptive names for functions and classes that reflect their purpose and responsibility. Names should make it evident what the function or class does.

  3. Short and Focused Functions:
    - Aim for short, focused functions that perform a single task. If a function is longer than a screen’s worth of code or has multiple levels of indentation, consider splitting it into smaller functions.

  4. Parameter Lists:
    - Limit the number of parameters a function accepts. Functions with many parameters can be challenging to use and understand. If necessary, use data structures like objects or maps to group related parameters.

  5. Avoid Deep Nesting:
    - Minimize nesting of functions and classes. Deeply nested code can become difficult to follow. Consider flattening your code structure when possible.

  6. Use Helper Functions and Methods:
    - Encapsulate common or repetitive logic into helper functions or methods. This reduces duplication and promotes reusability.

  7. Separation of Concerns:
    - Divide your code into separate functions or classes based on different concerns. For example, separate UI logic from business logic and data access.

  8. Class Encapsulation:
    - In Flutter, use classes to encapsulate related UI elements and behavior. For example, create custom widgets for specific UI components to keep your widget tree organized.

  9. Documentation:
    - Include comments or documentation that explain the purpose and usage of functions and classes. Well-documented code helps other developers understand your intentions.

  10. Code Reviews:

    • Conduct code reviews within your team to ensure that the codebase adheres to the practice of organizing code into small, focused units. Code reviews provide opportunities to identify and address issues.

Example

Here’s an example of organizing code into small functions and classes in Dart:

class ShoppingCart {
  List<CartItem> items = [];

  void addItem(Product product, int quantity) {
    final item = CartItem(product, quantity);
    items.add(item);
  }

  double calculateTotalPrice() {
    double totalPrice = 0;
    for (var item in items) {
      totalPrice += item.product.price * item.quantity;
    }
    return totalPrice;
  }
}

class CartItem {
  final Product product;
  final int quantity;

  CartItem(this.product, this.quantity);
}

In this example, the code is organized into two classes, ShoppingCart and CartItem, each with a single, well-defined responsibility. This makes the code more modular and easier to maintain.

Explain Properly Comment Your Code

  • Je pan function create karo aeni uper comment kari ne aeno use explain karvano jenathi code understand karvo easy pade. and /// no use karavano jyare class methods and functions nu documentation write karo tyare.
  • For example jo flutter ae aenu documentation j na banavyu hot to aapde shikhva mate ketlu hard thay so better che ke properly comment karvani code ma.

More in Details:

“Properly Comment Your Code” is a coding practice that involves adding comments and documentation to your source code to provide explanations, context, and additional information about the code’s functionality. Well-placed comments make your code more understandable and maintainable, especially for yourself and other developers who may work on the codebase in the future. Here’s why it’s important and how to do it effectively:

Why Properly Comment Your Code:

  1. Code Understanding: Comments help developers understand the purpose and behavior of the code, making it easier to work with and modify.

  2. Documentation: Comments serve as documentation, providing insights into the code’s intent, usage, and edge cases. They can also describe algorithms, data structures, and complex logic.

  3. Collaboration: When working in a team, comments enable effective collaboration. Team members can understand each other’s code, even if they didn’t write it.

  4. Maintenance: Code evolves over time. Comments provide guidance for maintaining and updating the codebase, preventing errors during modifications.

  5. Debugging: Comments can be valuable when debugging, as they provide context that can help you locate and fix issues more efficiently.

  6. Onboarding: For new team members or contributors, well-documented code with comments is easier to onboard to. It reduces the learning curve.

How to Properly Comment Your Code Effectively:

  1. Use Meaningful Comments:
    - Write comments that add value. Avoid obvious or redundant comments that merely restate the code. Focus on explaining why the code does something, not just what it does.

  2. Comment Header Blocks:
    - Start files, functions, classes, and significant sections of code with header blocks. These blocks include information such as the file’s purpose, author, date, and a brief description.

  3. Function and Method Comments:
    - Document function and method behavior, parameters, return values, and any special considerations. Use comments to explain what the function accomplishes, not just how it does it.

  4. Inline Comments:
    - Use inline comments sparingly and only when necessary. Inline comments should clarify complex or non-obvious code, not describe every line. Make sure to keep them up to date when code changes.

  5. Code Documentation Comments:
    - Use documentation comments for public APIs, classes, functions, and methods. In Dart, you can use /// for documentation comments, which can be processed by documentation generators.

/// This function calculates the total price of items in a cart.
/// The [items] parameter is a list of [CartItem] objects.
/// Returns the total price as a double.
double calculateTotalPrice(List<CartItem> items) {
  double totalPrice = 0;
  for (var item in items) {
    totalPrice += item.product.price * item.quantity;
  }
  return totalPrice;
}
  1. Update Comments During Maintenance:
    - As you make changes to your code, update the comments to reflect the current state and behavior of the code. Outdated comments can be misleading.

  2. Use a Consistent Comment Style:
    - Establish a consistent comment style throughout your codebase, including header blocks, function comments, and inline comments. Consistency enhances readability.

  3. Avoid Excessive Comments:
    - While comments are essential, avoid over-commenting your code. Code should be self-explanatory through meaningful variable names and clear structure. Comments should complement, not substitute for, readable code.

  4. Consider Using Markdown or Markup:
    - In documentation comments, consider using Markdown or markup languages to format your comments for better readability and to generate documentation.

  5. Code Reviews:

    • Include code review practices in your development process. Code reviews are an opportunity to ensure that comments are present, meaningful, and correctly reflect the code’s behavior.

Remember that while comments are beneficial, they should not be a substitute for writing clean, self-explanatory code. Comments should complement your code and provide additional insights that enhance code understanding and maintainability.

Use Proper Widget Composition

  • aapde flutter ma jyare user interfaces(UI) banavi ae tyare aena widget ne composing(Smalled Blocks) kari ne banavviae ae j best pratice che.
  • widget ni hierarchy create karvathi complex ui ne pan easy way ma write kari shakay che. 
  • everytime setState and provider no nana functions mate use nai karvano so better che aene seprate design kari ne aena buildcontext and updates ne control karvanu.

More in Details:

“Use Proper Widget Composition” is a best practice in Flutter development that emphasizes the importance of structuring your user interface (UI) by composing widgets in a logical and organized manner. Proper widget composition leads to more maintainable, readable, and efficient Flutter code.

Here’s a more detailed explanation of this practice:

  1. Widget Hierarchy: In Flutter, you build UIs by composing widgets. Each widget represents a piece of the UI, from simple elements like text or buttons to complex layouts and views. Proper widget composition involves creating a hierarchy of widgets to represent the structure of your UI.

  2. Reusability: Widgets are designed to be reusable. Instead of duplicating UI code, you should break it into smaller, reusable widgets. For example, if you have a complex UI element that appears in multiple places in your app, create a custom widget for it.

  3. Separation of Concerns: Follow the principle of separation of concerns. Keep UI-related code separate from business logic and data processing. This separation makes your code easier to maintain and test.

  4. Widget Organization: Organize your widgets hierarchically based on their relationships and responsibilities. For example, use Column and Row widgets to lay out other widgets vertically and horizontally, respectively. Use containers like ListView or GridView when dealing with lists of items.

  5. Composition Over Inheritance: In Flutter, you compose widgets to build complex UIs rather than relying on inheritance. Instead of extending existing widgets, create custom widgets that use existing ones as building blocks. This approach is more flexible and encourages code reusability.

  6. Keep Widgets Focused: Each widget should have a single responsibility. If a widget becomes too complex or handles too many tasks, consider breaking it into smaller, more focused widgets. This simplifies debugging and maintenance.

  7. Pass Data Using Constructor Parameters: When you create custom widgets, pass data and configuration to them using constructor parameters. This makes it explicit how a widget should behave and reduces reliance on global state.

Here’s an example to illustrate proper widget composition:

  • Suppose you’re building a weather app with a forecast screen that displays a list of daily weather forecasts. Instead of creating a single monolithic widget for the entire forecast screen, you can break it down into smaller widgets:

    • Create a custom WeatherForecast widget that takes a list of forecast data as a parameter.
    • Inside the WeatherForecast widget, use a ListView to display a list of DailyForecast widgets, each representing a single day’s forecast.
    • The DailyForecast widget takes a single forecast item as a parameter and displays the weather information for that day.
  • By composing these widgets, you create a clear and organized hierarchy, improve code reusability, and make it easier to manage and update the forecast screen in your app.

In summary, using proper widget composition in Flutter involves breaking down your UI into smaller, reusable widgets, organizing them hierarchically, and keeping them focused on specific responsibilities. This approach leads to cleaner, more maintainable code and a more efficient development process.

Avoid Deep Widget Nesting

  • Deep widget nesting means aek widget ni niche second and second ni niche third and third ni niche forth and so on. (example: ListView.builder)
  • Deep widget nesting ae code read and maintain karvama problem create karshe means aene samajvo ae hard thay jay che, so tamne jyare aevu lage ke bow batha widget nested thay che tyare aene smaller widget ma break karvanu consider karvu jove.

More in Details:

“Avoid Deep Widget Nesting” is a best practice in Flutter development that suggests minimizing the depth of widget hierarchies in your user interface (UI) to improve code readability, performance, and maintainability. Deep widget nesting occurs when you have a complex hierarchy of nested widgets, making your code harder to understand and potentially leading to performance issues.

Why avoid Deep Widget Nesting

Here’s why you should avoid deep widget nesting and some tips on how to do so:

  1. Readability: Deeply nested widget hierarchies can be challenging to read and understand, especially for other developers who may work on the code or for yourself when you revisit the code later. Keeping the widget tree shallow makes it easier to follow the flow of your UI.

  2. Debugging: Debugging becomes more difficult with deep nesting. When an issue arises in your UI, locating the source of the problem and understanding the context becomes more challenging. Shallow hierarchies simplify debugging.

  3. Performance: Although Flutter is designed to be fast, excessive widget nesting can lead to performance problems. Each widget in the hierarchy comes with some overhead. Deep nesting can result in unnecessary widget rebuilds, leading to reduced performance.

  4. State Management: Dealing with state management in deep widget hierarchies can be tricky. Passing data down the widget tree becomes cumbersome, and you may be tempted to use global state management solutions excessively. Shallow hierarchies make it easier to manage and pass state.

To avoid deep widget nesting in your Flutter code:

  1. Create Custom Widgets: Break down your UI into small, reusable custom widgets. Each widget should have a single responsibility. This practice allows you to compose your UI from simpler building blocks instead of creating complex widgets.

  2. Use Layout Widgets: Flutter provides layout widgets like Column, Row, ListView, Stack, and GridView to help you arrange and position child widgets efficiently. Utilize these layout widgets to structure your UI without excessive nesting.

  3. Extract Reusable Components: Identify UI elements that appear in multiple places within your app and extract them into separate custom widgets. This promotes code reuse and reduces nesting.

  4. Use Builder Widgets: In cases where you need to conditionally build parts of your UI, consider using builder widgets like Builder or FutureBuilder. These widgets can help you avoid adding unnecessary nesting.

  5. Consider Separation of Concerns: Separate your UI code from your business logic. This separation often leads to cleaner and less deeply nested widget hierarchies. Use state management solutions like Provider or Riverpod to manage and distribute data across your UI components efficiently.

  6. Flutter DevTools: Use the Flutter DevTools suite, particularly the “Widget Inspector,” to visualize your widget hierarchy and identify areas where nesting can be reduced.

Example

Here’s an example of how you might refactor a deeply nested widget hierarchy:

Before (Deep Nesting):

Column(
  children: [
    Text('Hello'),
    Container(
      child: Column(
        children: [
          Text('World'),
          // More nested widgets...
        ],
      ),
    ),
  ],
)

After (Reduced Nesting):

Column(
  children: [
    Text('Hello'),
    MyCustomWidget(), // Custom widget that handles nested content
  ],
)

In the refactored example, the deeply nested structure has been reduced to a more readable and maintainable layout by encapsulating the complex nesting within a custom widget (MyCustomWidget).

By following these practices and striving to keep your widget hierarchy shallow and organized, you can create Flutter applications that are easier to understand, maintain, and perform efficiently.

Keep UI and Business Logic Separated

  • Separate your UI code from your business logic. This can help with testing and code maintainability. Consider using packages like bloc(preferred) or provider for state management.

More in Details

“Keep UI and Business Logic Separated” is a fundamental principle in software development that advocates for a clear separation between the user interface (UI) and the business logic of an application. This separation, often referred to as the Model-View-Controller (MVC), Model-View-Presenter (MVP), or Model-View-ViewModel (MVVM) architecture, helps improve the maintainability, testability, and scalability of your Flutter application.

Here’s a breakdown of this principle and its benefits:

  1. Separation of Concerns (SoC): Separating UI and business logic adheres to the SoC principle, which states that different aspects of software should be handled independently and not intermingle. In the context of Flutter, this means keeping code responsible for how the UI looks and behaves separate from code responsible for the underlying data, calculations, and application logic.

  2. Maintainability: When UI and business logic are separated, changes to one part of the application are less likely to affect the other. This makes it easier to maintain and update your codebase. UI designers and developers can work on the UI components without worrying about the intricacies of the application’s logic.

  3. Testability: Separating UI and business logic allows for more effective testing. You can write unit tests for the business logic independently of the UI. This promotes a test-driven development (TDD) approach, where you write tests before implementing the functionality, ensuring that your code is robust and less error-prone.

  4. Reusability: Isolating the business logic from the UI makes it possible to reuse the same logic in different parts of the application or even across multiple applications. For instance, you can create a business logic layer that can be shared across different Flutter projects.

How can help keep UI and Business Logic Seprated:

In the context of Flutter, here’s how you can keep UI and business logic separated:

  1. Use State Management: Employ state management solutions like Provider, Riverpod, or Bloc to manage application state. These libraries help you separate the UI (widgets) from the underlying data and logic by providing a clear mechanism for passing data and events between them.

  2. ViewModels and Models: Utilize ViewModels to encapsulate the UI-related logic and Models to represent the data structures. This approach follows the MVVM pattern and ensures a clean separation between UI components and the logic that drives them.

  3. Business Logic Classes: Implement business logic in separate Dart classes or packages. These classes should not have direct dependencies on Flutter widgets or context. They should be purely Dart code responsible for performing calculations, making API calls, and managing application data.

  4. UI Widgets: Design your UI using Flutter widgets. These widgets should focus solely on rendering and responding to user interactions. Minimize the amount of application logic embedded within widgets, and instead, delegate tasks to the appropriate business logic classes or ViewModels.

  5. Dependency Injection: Use dependency injection techniques to provide business logic classes or ViewModels to your UI widgets. This ensures that the UI components are decoupled from the specific implementations of the business logic, making it easier to switch or test different implementations.

  6. Testing: Write tests for your business logic independently of the UI. Flutter’s testing framework allows you to write unit tests and widget tests to ensure that both UI and logic work as expected.

By adhering to the principle of keeping UI and business logic separated, you can create Flutter applications that are easier to maintain, test, and scale. This separation promotes code organization and modularity, making your codebase more robust and maintainable as your application grows and evolves.

Use Flutter DevTools

  • Flutter provides a powerful set of tools for debugging and profiling your application. Familiarize yourself with Flutter DevTools to help identify and resolve issues in your code efficiently.

More in Details

Flutter DevTools is a suite of developer tools and utilities provided by the Flutter team to assist developers in building, debugging, profiling, and analyzing Flutter applications. DevTools offers a range of features and capabilities that help streamline the development process and improve the overall quality of your Flutter apps. Here’s an explanation of some of the key features and how to use them:

Use of Tools in DevTools

  1. Widget Inspector:
    - The Widget Inspector allows you to interactively explore the widget tree of your Flutter application.
    - You can select widgets in your running app and inspect their properties and state.
    - Use it to debug layout issues, identify widget rebuilds, and understand the widget hierarchy.

  2. Timeline:
    - The Timeline provides a detailed view of your app’s performance over time.
    - You can capture and analyze frames, track UI thread and GPU work, and find performance bottlenecks.
    - This is particularly useful for optimizing app performance and identifying rendering issues.

  3. Debugger:
    - Flutter DevTools includes a built-in debugger that lets you set breakpoints, step through code, and inspect variables.
    - You can also view the call stack and navigate through your app’s code while it’s running.

  4. Logging:
    - DevTools provides a log viewer that displays print and debug output from your app.
    - You can filter logs based on severity and search for specific messages.

  5. Memory Profiler:
    - The Memory Profiler allows you to track memory usage and identify memory leaks in your Flutter app.
    - You can take memory snapshots and analyze object allocation over time.

  6. Network Profiler:
    - The Network Profiler helps you monitor network requests made by your app.
    - You can view details of HTTP requests and responses, including headers and payload data.

  7. Performance Overlay:
    - The Performance Overlay is a widget that can be added to your app to visualize performance metrics directly on the screen.
    - It displays information like frames per second (FPS), GPU rendering, and CPU usage.

  8. Dart DevTools Integration:
    - DevTools is closely integrated with Dart DevTools, which offers additional features for Dart development.
    - Dart DevTools includes features for analyzing and debugging Dart code, including observatory, heap snapshots, and more.

How to use Flutter DevTools

Here’s how to use Flutter DevTools in your development workflow:

  1. Install Flutter DevTools:
    - You can install DevTools as a Flutter package by running the following command in your terminal:

    flutter pub global activate devtools
    

  2. Launch DevTools:
    - Run your Flutter app, and then open DevTools by running this command:

    flutter pub global run devtools
    

    - DevTools will open in your default web browser, providing access to all its features.

  3. Connect to Your App:
    - DevTools will automatically detect your running Flutter app.
    - If you’re using a different device or need to specify a custom URL, you can manually connect DevTools to your app.

  4. Explore and Use DevTools:
    - Navigate through the various tabs and panels in DevTools to access the features you need.
    - Use the Widget Inspector to examine the widget tree, the Timeline to analyze performance, and other tools as required for your development and debugging tasks.

  5. Customization and Preferences:
    - DevTools offers customization options and preferences that allow you to tailor its behavior to your specific needs.

Flutter DevTools is an invaluable resource for Flutter developers, whether you’re building new apps, optimizing performance, or debugging issues. By leveraging its features, you can streamline your development process and create high-quality Flutter applications.

Test Your Code

  • Write unit tests and widget tests to ensure that your code functions as expected. Flutter has built-in support for testing, making it easy to write and run tests.

More in Details

“Test Your Code” is a crucial practice in software development, including Flutter development, that involves systematically creating and running tests to verify that your code behaves as expected. Testing helps ensure that your application works correctly, remains reliable during updates, and can be maintained more easily. In the context of Flutter, there are different types of tests you can write:

Type Of Testing

  1. Unit Tests:
    - What: Unit tests focus on testing individual units of code in isolation, typically functions, methods, or small classes.
    - Why: They help verify that each part of your codebase works as intended independently of the rest of the application. This practice aids in catching bugs early in development.
    - How: In Flutter, you can write unit tests using the test package or Flutter’s built-in test framework. Mocking dependencies or using test doubles (like Mockito) is common to isolate units for testing.

  2. Widget Tests:
    - What: Widget tests are used to test individual widgets or small groups of widgets. These tests interact with widgets and check their behavior.
    - Why: Widget tests help ensure that UI components render correctly and respond to user interactions as expected.
    - How: You can write widget tests using Flutter’s flutter_test package. These tests can simulate user interactions and verify widget properties and state changes.

  3. Integration Tests:
    - What: Integration tests involve testing how different parts of your application work together. These tests often cover complete user flows and interactions between various components.
    - Why: Integration tests help ensure that the different parts of your app integrate correctly and that end-to-end functionality works as expected.
    - How: Flutter provides the flutter_driver package for writing integration tests. These tests run on a real or emulated device, interact with your app, and can validate the entire user journey.

  4. Golden Tests (Snapshot Tests):
    - What: Golden tests are a type of widget test that captures the rendered output of a widget and compares it to a “golden” image or snapshot.
    - Why: They help detect unintended UI changes, ensuring that the UI remains consistent across different Flutter versions or device configurations.
    - How: Use the flutter_test package’s goldenFileComparator to create and validate golden tests.

How to integrate in flutter

Here’s how to integrate testing into your Flutter development workflow:

  1. Write Tests Alongside Code: Practice test-driven development (TDD) by writing tests before implementing the corresponding code. This ensures that your code is designed with testability in mind and helps catch issues early.

  2. Use Test Frameworks and Libraries: Flutter provides built-in support for testing, including the test package for unit tests and the flutter_test package for widget and golden tests. You can also use additional packages like Mockito for mocking and integration_test for integration tests.

  3. Continuous Integration (CI): Set up CI pipelines to automatically run your tests whenever changes are pushed to your code repository. Popular CI/CD platforms like GitHub Actions, Travis CI, and CircleCI work well with Flutter testing.

  4. Test Coverage: Track test coverage to ensure that your tests cover a significant portion of your codebase. Tools like lcov or packages like coverage can help you measure and visualize code coverage.

  5. Refactoring and Maintenance: Whenever you refactor or modify your code, run your tests to ensure that the changes don’t introduce regressions or break existing functionality.

  6. Parameterized Tests: Write parameterized tests to test multiple scenarios with different input data, making your test suite more comprehensive.

  7. Documentation: Maintain documentation for your tests. Describe what each test is validating and why it’s important. Well-documented tests make it easier for other developers to understand your code.

  8. Test Isolation: Ensure that tests are isolated from external dependencies like databases or web services. Use mocking or dependency injection to replace these dependencies with test-specific versions.

By regularly testing your Flutter code using the appropriate types of tests, you can increase the reliability and maintainability of your application, catch and fix bugs early, and have confidence that your app behaves correctly across different scenarios and updates.

Stay Up-to-Date

  • Flutter is an evolving framework, and best practices can change over time. Keep up-to-date with Flutter updates, new packages, and community recommendations to improve your code quality.

More in Details

“Stay Up-to-Date” is a critical best practice in software development, including Flutter development. It involves actively keeping yourself informed about the latest updates, changes, and trends in the Flutter framework, associated packages, and the broader software development ecosystem. Staying up-to-date ensures that you can make informed decisions, adopt best practices, and take advantage of new features and improvements. Here’s why staying up-to-date is important and how to do it effectively:

Why Stay Up-to-Date:

  1. New Features and Enhancements: Flutter is an evolving framework, and updates often introduce new features, improvements, and performance optimizations. Staying up-to-date allows you to take advantage of these enhancements in your projects.

  2. Bug Fixes and Security Patches: Updates may include bug fixes and security patches. Applying these updates promptly helps keep your applications secure and free of known issues.

  3. Compatibility: As Flutter evolves, package dependencies and compatibility may change. Staying up-to-date ensures that your app remains compatible with the latest versions of Flutter and its dependencies.

  4. Performance: Newer versions of Flutter may include performance optimizations that can make your apps run faster and smoother. Staying current can help you deliver a better user experience.

  5. Community and Best Practices: Staying engaged with the Flutter community and following best practices is crucial for learning from others’ experiences, sharing knowledge, and improving your own coding practices.

  6. Emerging Trends: Technology trends can impact your application’s design and functionality. Keeping up-to-date allows you to evaluate and adopt emerging trends that may be relevant to your projects.

How to Stay Up-to-Date:

  1. Official Documentation and Announcements:
    - Regularly check the official Flutter documentation (https://flutter.dev/docs) and announcements on the Flutter website to learn about the latest features, updates, and best practices.

  2. Release Notes:
    - Read the release notes for Flutter and related packages. These notes provide detailed information about what has changed in each new release.

  3. Flutter Blog and Newsletters:
    - Subscribe to the Flutter blog (https://flutter.dev/blog) and newsletters to receive updates, tutorials, and insights directly from the Flutter team.

  4. Social Media and Forums:
    - Follow Flutter-related accounts and communities on social media platforms like Twitter and Reddit. Engaging in discussions and forums like the Flutter subreddit (r/FlutterDev) can keep you informed and provide opportunities to ask questions and share knowledge.

  5. Conferences and Meetups:
    - Attend Flutter conferences, webinars, and local meetups when possible. These events often feature presentations on the latest developments in Flutter.

  6. Online Courses and Tutorials:
    - Enroll in online courses and tutorials related to Flutter. Platforms like Udemy, Coursera, and Pluralsight offer courses that cover Flutter development.

  7. GitHub Repositories:
    - Monitor GitHub repositories for Flutter and popular Flutter packages. You can see the latest commits, issues, and discussions related to these projects.

  8. Version Management:
    - Use a version management tool like pub (the Dart package manager) or pubspec.yaml to specify the Flutter and package versions in your projects. Regularly update these dependencies to stay current.

  9. Experiment and Build Projects:
    - Experiment with new Flutter features and try building small projects to gain hands-on experience with the latest updates.

  10. Community Involvement:

    • Actively participate in the Flutter community by sharing your knowledge, answering questions, and contributing to open-source projects. This can help you stay engaged and build a network of fellow Flutter developers.

Remember that staying up-to-date is an ongoing process, and the Flutter ecosystem evolves continuously. Regularly allocating time for learning and keeping current with Flutter developments is essential for maintaining the quality and competitiveness of your Flutter applications.

Analyse and Format Your Code

  • Use tools like dart analyse and dart format to ensure your code adheres to best practices and formatting guidelines.

More in Details

“Analyse and Format Your Code” are essential practices in software development, including Flutter development, that involve reviewing your code for potential issues, errors, and style inconsistencies while also ensuring that your code adheres to a consistent and readable format. These practices help maintain code quality, readability, and consistency throughout your projects. Here’s a breakdown of these two practices:

Analyze Your Code:

Analyzing your code involves using static analysis tools and linters to identify potential issues, bugs, and code smells without executing the code. In the context of Flutter development, you can use the Dart analysis tool, which is integrated into Flutter’s development environment. Here’s how to analyze your code:

  1. Use the Dart Analyzer: The Dart Analyzer is a static analysis tool that comes bundled with the Dart SDK and Flutter. It checks your code for a wide range of issues, including syntax errors, type mismatches, unused variables, and more.

  2. IDE Integration: Most popular Flutter IDEs, such as Visual Studio Code and Android Studio, integrate the Dart Analyzer seamlessly. You’ll see error and warning highlights in your code editor as you write code.

  3. Command-Line Usage: You can run the Dart Analyzer from the command line using the dart analyze command. This is useful for batch analysis or integrating with continuous integration (CI) pipelines.

  4. Analyze and Address Issues: Regularly run the analyzer on your project and address any issues it identifies. The goal is to have a codebase with zero analysis issues.

  5. Custom Analysis Rules: You can define custom analysis rules for your codebase using packages like lint. This allows you to enforce project-specific coding standards and best practices.

Format Your Code:

Formatting your code ensures that it follows a consistent style and layout, making it more readable and maintainable. For Dart and Flutter development, the recommended tool for code formatting is dartfmt. Here’s how to format your code:

  1. Use dartfmt: dartfmt is a command-line tool that automatically formats your Dart and Flutter code according to the official Dart style guide. It enforces consistent code formatting across your project.

  2. IDE Integration: Most Flutter IDEs integrate dartfmt and provide automatic code formatting when you save a file or through keyboard shortcuts (e.g., Shift + Alt + F in Visual Studio Code).

  3. Pre-commit Hooks: Set up pre-commit hooks in your version control system (e.g., Git hooks) to automatically format your code before each commit. This ensures that no unformatted code makes it into your repository.

  4. Continuous Integration: Incorporate code formatting into your CI/CD pipeline. Ensure that your codebase remains correctly formatted throughout development.

  5. Custom Style Configuration: If needed, you can configure your own code style rules by creating an .analysis_options file in your project and specifying your preferred formatting rules. You can also adjust line lengths, indentation, and other formatting options.

  6. EditorConfig: Consider using an .editorconfig file to define project-wide coding style preferences, including indentation, line endings, and other code formatting settings. Many IDEs support EditorConfig files.

By consistently analyzing and formatting your code, you improve code quality, readability, and maintainability. It also helps ensure that your codebase is consistent, which is especially valuable when working in a team or on open-source projects. Additionally, it reduces the likelihood of introducing subtle bugs and issues due to code formatting discrepancies.

Document Your Code

  • Use documentation comments to describe the purpose, parameters, and return values of functions and classes. This helps other developers understand how to use your code.

More in Details

“Document Your Code” is a crucial best practice in software development, including Flutter development. It involves adding comments, annotations, and documentation to your code to make it more understandable and maintainable for both yourself and other developers who may work on the project. Proper documentation helps convey the purpose, usage, and implementation details of your code. Here’s why documenting your code is important and how to do it effectively:

Why Document Your Code:

  1. Code Understanding: Well-documented code is easier to understand. Developers can quickly grasp the intent and functionality of code segments, even if they didn’t write them.

  2. Collaboration: When working on a team project, documentation is crucial for effective collaboration. It helps team members understand each other’s contributions and reduces the learning curve for new team members.

  3. Maintenance: Code evolves over time. Documentation serves as a guide for maintaining and updating the code. When you revisit your code after months or years, clear documentation can be a lifesaver.

  4. Debugging: Comments can provide insights into the logic and reasoning behind specific code decisions. This can be invaluable when debugging issues or addressing unexpected behavior.

  5. Onboarding: For open-source projects or when onboarding new team members, well-documented code makes it easier for newcomers to get up to speed quickly.

How to Document Your Code Effectively:

  1. Use Meaningful Variable and Function Names:
    - Choose descriptive and meaningful names for variables, functions, classes, and other code elements. Well-named entities reduce the need for excessive comments.

  2. Comments:
    - Add comments to explain complex algorithms, non-obvious logic, or any part of your code that may not be immediately clear to others. Use comments to provide context, not just describe what the code does.
    - Follow a consistent commenting style, such as using double slashes (//) for single-line comments and /// for documentation comments that generate documentation files.

// Calculate the sum of two numbers
int add(int a, int b) {
  return a + b;
}
  1. Documentation Comments:
    - Use documentation comments (also known as doc comments) for classes, functions, methods, and other public API elements. These comments can be automatically generated into documentation using tools like Dart’s dartdoc.
    - Include details about the purpose of the entity, its parameters, return values, and usage examples.
/// A class representing a person.
class Person {
  /// The person's name.
  String name;

  /// The person's age.
  int age;

  /// Creates a new [Person] instance with the given [name] and [age].
  Person(this.name, this.age);
}
  1. Keep Comments Updated:
    - Maintain your comments alongside code changes. Outdated comments can mislead developers and lead to misunderstandings.

  2. Coding Standards and Style Guides:
    - Adhere to coding standards and style guides, which often include recommendations for commenting and documentation practices. In the Dart and Flutter ecosystem, you can refer to the official Dart Effective Dart Style Guide for guidance.

  3. Javadoc/Docstring Conventions:
    - Consider following Javadoc or docstring conventions for documentation comments. These conventions specify how to format comments to ensure consistency and generate useful documentation.

  4. Use Inline Comments Sparingly:
    - Inline comments should be used judiciously and only for complex or non-intuitive code sections. The code itself should be self-explanatory with clear variable names and functions.

  5. Documentation Generators:
    - Leverage documentation generators like dartdoc to automatically generate documentation from your code comments. This makes it easier to create and maintain documentation.

  6. README Files and Documentation Files:
    - Beyond inline comments and doc comments, maintain a README.md file in your project’s root directory to provide a high-level overview of your project and its usage. Consider using Markdown for formatting.

By following these practices, you can create well-documented Flutter projects that are more understandable, maintainable, and accessible to other developers. Clear and concise documentation is an investment in the long-term success and sustainability of your codebase.

Use Version Control

  • Always use version control systems like Git to track changes in your code. This helps you collaborate with others and revert changes if needed.

More in Details

“Use Version Control” is a fundamental best practice in software development, including Flutter development. Version control systems (VCS) are tools that help you manage and track changes to your codebase over time. Flutter developers often use Git, a distributed version control system, to implement this practice. Here’s an explanation of why version control is crucial and how to use it effectively in your Flutter projects:

Why Use Version Control:

  1. History Tracking: Version control systems keep a detailed history of changes made to your codebase, allowing you to see who made a change, when it was made, and what exactly was changed. This historical information is invaluable for understanding how your code has evolved.

  2. Collaboration: When working on a team or collaborating with others, version control facilitates concurrent development. Multiple developers can work on different aspects of the project simultaneously, and version control helps merge their changes together.

  3. Backup and Recovery: Version control serves as a reliable backup system. If something goes wrong with your code, you can revert to a previous, known-good state. This backup and recovery capability can prevent data loss and code disasters.

  4. Branching and Experimentation: Version control systems enable you to create branches, which are isolated copies of your code. You can use branches for feature development, bug fixes, and experimentation without affecting the main codebase. This promotes safe and controlled development.

  5. Code Reviews: Version control facilitates code reviews by providing a structured way for team members to collaborate on code changes. Code reviews are essential for maintaining code quality and sharing knowledge.

  6. Release Management: You can use version control to manage releases and track which versions of your software have been deployed. This is crucial for tracking and deploying updates to production.

How to Use Version Control in Flutter Projects:

  1. Install Git: If you haven’t already, install Git on your development machine. You can download Git from the official website (https://git-scm.com/).

  2. Initialize a Git Repository: To start using version control in a Flutter project, navigate to the project’s root directory in your terminal and run git init. This command initializes a new Git repository.

  3. Add and Commit Changes:
    - Use git add to stage changes you want to commit. You can specify individual files or directories.
    - Use git commit to commit your staged changes along with a descriptive commit message. A good commit message should explain what the change does.

  4. Create Branches:
    - Use git branch to list existing branches.
    - Use git checkout -b <branch-name> to create and switch to a new branch.
    - Use git checkout <branch-name> to switch between branches.

  5. Merge Branches:
    - Use git merge <branch-name> to merge changes from one branch into another. Merging is common when you’ve completed a feature or bug fix in a separate branch.

  6. Remote Repositories:
    - To collaborate with others, you’ll typically use remote repositories hosted on platforms like GitHub, GitLab, or Bitbucket. Connect your local repository to a remote using git remote add origin <repository-url> and push your changes using git push origin <branch-name>.

  7. Pull Changes: Before making changes to your codebase, it’s a good practice to pull the latest changes from the remote repository to ensure you’re working with the most up-to-date code.

  8. Resolve Conflicts: When merging branches or pulling changes, conflicts may arise if multiple people modify the same code. Use git mergetool or manually edit the conflicting files to resolve conflicts.

  9. Commit History: Use git log to view the commit history of your project. This helps you understand how your codebase has evolved.

  10. Tagging Releases: You can use Git tags to mark specific commits as releases. This helps you keep track of important versions of your software.

By following these steps and best practices, you can effectively use version control to manage your Flutter projects. Git is a powerful tool that enhances collaboration, code quality, and project management in software development.

Remember that good code practices may vary depending on the project and team, but these guidelines can serve as a solid foundation for writing clean and maintainable Flutter code.


Last update: 19 octobre 2023
Created: 16 septembre 2023