Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Coding Guidelines

Daniel edited this page Nov 7, 2019 · 19 revisions

We use the following sources as coding guidelines.

Additionally we apply the following rules.

Flutter / Dart

Dart is the main programming language of this project, while Flutter is the UI framework to create all interfaces. The following general rules apply:

Naming

General

  • We always use the singular form for naming (use the suffix List or similar for a collection of items)
    • This applies to classes, methods, variables and so on
    • Example: class ChatItem {}, var chatItem, var chatItemList, ChatItem getChatItem(), List<ChatItem> getChatItemList()

Widgets / States / Events

  • Stateless and stateful widgets should get no prefix or suffix (e.g. ChatList)
  • State objects should get the suffix State (e.g. ChatListState)
  • Event objects should get the suffix Event (e.g. ChatListEvent)
  • If components belong together the name should state that by prefixing the components with the context
  • A name should be structured starting with the context, continuing with actual name and if necessary suffixed with a programming language specific word (e.g. ContactManagerMixin, context = Contact, name = Manager, programming language specific word = Mixin)

Create and destroy logic / state methods

  • As Flutter uses the words build and create pretty extensively for UI handling, we should avoid those when creating methods which manage logic or states
    • Create / setup methods should start with setup
    • Tear down / destroy methods should start with tearDown

Create and destroy UI methods

  • As Flutter uses the words build and dispose for UI tasks, we should also do so when providing widgets
    • Create / setup methods should start with build
    • Tear down / destroy methods should start with dispose

Widgets

Widgets are the core component of the app, as Flutter defines every component as a Widget.

General rules

Keys

Keys are required by the Flutter framework to identify if a Widget can be reused.

  • Keys must reflect the build / rebuild state of a Widget

Additionally keys are used to perform tests (see https://flutter.dev/docs/cookbook/testing). To be able to test the app via integration or widget tests we needs keys for all important widgets, so the tests are able to identify the widgets.

  • Every widget which allows user interaction (buttons, text fields and so on) should have a key
  • Keys are defined as constants in utils/keyMapping.dart
    • Use in production code Key(keyProviderSignInEmailTextField)
    • Use in test code find.byValueKey(keyProviderSignInEmailTextField)
  • Naming (e.g. keyProviderSignInEmailTextField)
    • Starts with "key" as prefix
    • Followed by the global context, so the file or class, e.g. "ProviderSignIn"
    • Followed by the context within the file or class, e.g. "Email"
    • Followed by the type of the widget, e.g. TextField (shortening is allowed, as long as the context is still understandable, e.g. TextField is allowed if a ValidatableTextFormField is used)

Internationalization

  • Don't use strings directly within source files (e.g. ButtonText("Login"))
  • The l10n package should get used (based on gettext, but adapted to avoid coding errors)
    • Add a string in the L.dart file. It serves as key / default string, but is usable via a constant expression during development phase
  • As soon as a new translation round is started, the string gets translated and the new .po files will be integrated. Everything else will be handled automatically

Dimensions

  • Don't use dimension values directly within source files (e.g. Padding(8.0))
  • The dimensions.dart file located in the ui package should get used
    • Every entry in this file should be a constant
    • Duplicated values are fine if the context of the constant differs
    • Entries are used by importing dimensions.dart and using the constants directly (e.g. listItemPadding)

Colors

  • Don't use color values directly within source files (e.g. Colors.red)
  • The color.dart file located in the ui package should get used
    • Every entry in this file should be a constant
    • Duplicated values are fine if the context of the constant differs
    • Entries are used by importing colors.dart and using the constants directly (e.g. onBackground)
    • Values in this file shouldn't get altered / added / removed without prior discussion with the design team

TextStyles

  • Don't use text styles directly within source files if multiple values are applied (e.g. TextStyle(color: Colors.red, ..., ...)), for single values (e.g. only color:) direct usage is allowed
  • If possible every text style should extend existing Flutter styles. Use Theme.of(context).textTheme
  • The text_styles.dart file located in the ui package should get used to extend existing Flutter styles
    • Every entry in this file should be a constant
    • Duplicated values are fine if the context of the constant differs
    • Entries are used by importing styles.dart and using the constants directly (e.g. primaryW500)

Utils

Beside the mentioned classes other utils exists. If generic functionality is needed please check first if a utility class / method / function already provides the required functionality. If this is not the case a new utility class should be created or an existing one should get extended to avoid duplicated code.

File structure

  • Stateless, stateful and state classes of one context should be located in one file
    • Classes should be library private (prefixed with an underscore) if possible
  • Events and states for BloC classes should be located in one file
  • All files referring to a context (e.g. contacts) should be located in one package