Coding Style

The important part of good code is good style

Search by using Rex

Search and replace toBean by Rex : static .? toBean(.?) => .?(.?);

Useful

  • Always try to use existing feature or function

// not recommend
var result = double.parse('some string');
//1. This code could be have error or crash app 
//   when string value not able to case into double
import 'package:infinity_core/core.dart';

var result = 'some string'.secureDouble;
// 1. use existing build in function, 
// if some string have invalid format it function will take care for us.
  • Early return when function with condition

    if(true){
        return;
    }
    if(false){
        return;
    }
  • Use extension, extension, extension everywhere

    // not recommend
        AppBar(
            backgroundColor: Theme.of(this).colorScheme.inversePrimary,
            title: const Text('API URL', textAlign: TextAlign.center),
        );
        ElevatedButton(
            onPressed: _settingOnPressed,
            style: ButtonStyle(backgroundColor: WidgetStateProperty.all<Color>(Theme.of(this).colorScheme.inversePrimary)),
            child: Text(_isEditApi ? 'Done' : 'Change API'),
        );
    // This code have use inversePrimary which is primary color, and this color base on context and use multiple place. 
    // do not copy and write redundancy 
    
    
    // recommend
        extension BuildContextExtension on BuildContext {
          Color get colorPrimary => context.colorPrimary;
        };
        AppBar(
            backgroundColor: context.colorPrimary,
            title: const Text('API URL', textAlign: TextAlign.center),
        );
        ElevatedButton(
            onPressed: _settingOnPressed,
            style: ButtonStyle(backgroundColor: WidgetStateProperty.all<Color>(context.colorPrimary)),
            child: Text(_isEditApi ? 'Done' : 'Change API'),
        );
    // To resolve about case we can create other extension for context. 
    // next time we only need to write context.colorPrimary.
  • Put it as private if we use it only in the same file.

    class MyClass {
      String _privateVariable = "This is private";
      
      String publicVariable = "This is public";
    
      void _privateMethod() {
        print("This is a private method.");
      }
    
      // Public method (accessible from other files)
      void publicMethod() {
        print("This is a public method.");
        // Calling the private method from within the same file
        _privateMethod();
      }
    }
    
    void main() {
      MyClass myClass = MyClass();
    
      print(myClass.publicVariable);
      myClass.publicMethod();
    
      // Accessing the private variable and method will result in a compile-time error
      // print(myClass._privateVariable); // Error: '_privateVariable' isn't defined
      // myClass._privateMethod();        // Error: '_privateMethod' isn't defined
    }
    
  • Try not to cast or repeated declare type

    void main() {
      var myClass = MyClass();  // Using 'var' instead of repeating type
    
      print(myClass.publicVariable);
      myClass.publicMethod();
    }
    
  • Declare with short name, should not allow to put type on left and right

    class UserInfo {
      var _status = "Active";
      
      var userName = "John Doe";
    
      void showInfo() {
        print(userName);  // Accessing public variable
        _logStatus();     // Call to private method
      }
    }
    
    void main() {
      var user = UserInfo();  // Using var and meaningful name
    
      print(user.userName);
      user.showInfo();
    }
    
  • Avoid using generic type like user can put any value into that function.

    class UserInfo {
      String _status = "Active";
    
      String userName = "John Doe";
      
      // Public method to set user status with strict type
      void setStatus(String newStatus) {
        _status = newStatus;
      }
    }
    
    void main() {
      var user = UserInfo();
    
      user.setStatus("Inactive");
    }
    
  • If it have default value from model try not to put with default value, but put it in model directly.

    class UserInfo {
      // Properties with no default values declared directly
      String userName;
      String _status;
    
      // Constructor with default values 
      UserInfo({String? userName, String? status})
          : userName = userName ?? "John Doe",  // Default value assigned here
            _status = status ?? "Active"; 
    }
    
  • Try use existing function, do not use by manual, example 1. var.isEmpty()

    void main() {
      var user = UserInfo();
    
      // Not recommend
      if(user.userName != ''){
      
      }
      
      // Recommend
      print(user.userName.isEmpty()); // True  
    }
  • Try to use type define by model not need to use like toString()

    void main() {
      // Creating a UserInfo without specifying the userName and status
      var user = UserInfo();
    
      // Not recommend
      print(user.userName.toString());  
    
      // Recommend
      print(user.userName); // Its already string type as define in Model
    }

Identifiers

Identifiers come in three flavors in Dart.

  • UpperCamelCase names capitalize the first letter of each word, including the first.

  • lowerCamelCase names capitalize the first letter of each word, except the first which is always lowercase, even if it's an acronym.

  • lowercase_with_underscores names use only lowercase letters, even for acronyms, and separate words with _.

DO name types using UpperCamelCase

Classes, enum types, typedefs, and type parameters should capitalize the first letter of each word (including the first word), and use no separators.

good
class SliderMenu { ... }

class HttpRequest { ... }

typedef Predicate<T> = bool Function(T value);

DO name extensions using UpperCamelCase

Like types, extensions should capitalize the first letter of each word (including the first word), and use no separators.

extension MyFancyList<T> on List<T> { ... }

extension SmartIterable<T> on Iterable<T> { ... }

DO name packages, directories, and source files using lowercase_with_underscores

Some file systems are not case-sensitive, so many projects require filenames to be all lowercase. Using a separating character allows names to still be readable in that form. Using underscores as the separator ensures that the name is still a valid Dart identifier, which may be helpful if the language later supports symbolic imports.

good
my_package
└─ lib
   └─ file_system.dart
   └─ slider_menu.dart
bad
mypackage
└─ lib
   └─ file-system.dart
   └─ SliderMenu.dart

DO name import prefixes using lowercase_with_underscores

good
import 'dart:math' as math;
import 'package:angular_components/angular_components.dart' as angular_components;
import 'package:js/js.dart' as js;
bad
import 'dart:math' as Math;
import 'package:angular_components/angular_components.dart' as angularComponents;
import 'package:js/js.dart' as JS;

DO name other identifiers using lowerCamelCase

Class members, top-level definitions, variables, parameters, and named parameters should capitalize the first letter of each word except the first word, and use no separators.

good
var count = 3;

HttpRequest httpRequest;

void align(bool clearItems) {
  // ...
}

PREFER using lowerCamelCase for constant names

In new code, use lowerCamelCase for constant variables, including enum values.

good
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');

class Dice {
  static final numberGenerator = Random();
}
bad
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');

class Dice {
  static final NUMBER_GENERATOR = Random();
}

Last updated