Search code examples
flutterdartearly-return

Return Early Pattern in Dart/Flutter and splitting up methods


I'm a long-time c# developer and now learning Dart/Flutter. In c#, I prefer the Return Early Pattern, for example:

private void myHandler()
{
    if (checkSomething())
    {
        doSomething();
        return;
    }

    if (checkSomethingElse())
    {
        doSomethingElse();
        return;
    }

    doRegularStuff();
}

Is that generally considered good practice in Dart as well? I created the following keyboard handler in Dart, inspired by various examples I found online. For formatting, I've used the dart format command line command. I find it really ugly to be honest:

  /// Handles key presses.
  KeyEventResult _keyPressed(FocusNode node, KeyEvent event) {
    if (event is! KeyDownEvent) return KeyEventResult.ignored;
    if (event.isBarcodeChar()) {
      _keyboardBuffer.write(event.character);
    } else if (event.isBackspaceKey() && _keyboardBuffer.isNotEmpty) {
      String shortenedBuffer =
          _keyboardBuffer.toString().substring(0, _keyboardBuffer.length - 1);
      _keyboardBuffer.clear();
      _keyboardBuffer.write(shortenedBuffer);
    } else if (event.logicalKey == LogicalKeyboardKey.enter) {
      _codeScanned(_keyboardBuffer.toString());
      _keyboardBuffer.clear();
    } else {
      return KeyEventResult.ignored;
    }
    return KeyEventResult.handled;
  }

  /// Handles scaned barcodes.
  void _codeScanned(String code) {
    // Handle some stuff and update the state of the application
  }
}

The code of the _keyPressed method doesn't really make clear, when it returns handled or ignored. It also looks really clumped together. I've also learned in c#, that all those else if statements have a bad smell. So would it be a good pracitce in Dart to use the Return Early Pattern as well?

Bonus question: Is it considered good practice in Dart to create single-use methods like my void _codeScanned() to improve readability? The method is only used from within the keyboard handler and nowhere else.

The official Dart coding guideline is rather unclear in this aspect (or I'm too stupid to find the right chapter). So thank you for your profound help in advance.


Solution

  • There is nothing bad in using Return Early patern. It's using widely, you could take a look on the either_dart package, for example.

    Regarding functions which are called only once, I prefer to use inline functions. So I have done a little refactoring of your code to make it more readable:

    KeyEventResult _keyPressed(FocusNode node, KeyEvent event) {
      void _codeScanned(String code) {
        //
        _keyboardBuffer.clear();
      }
    
      bool canDoBackspace() =>
         event.isBackspaceKey() && _keyboardBuffer.isNotEmpty;
    
      bool isEnter() => event.logicalKey == LogicalKeyboardKey.enter;
    
      void doBackspace() {
        String shortenedBuffer =
          _keyboardBuffer.toString().substring(0, _keyboardBuffer.length - 1);
        _keyboardBuffer.clear();
        _keyboardBuffer.write(shortenedBuffer);
      }
    
      if (event is! KeyDownEvent) {
        return KeyEventResult.ignored;
      }
      if (event.isBarcodeChar()) {
        _keyboardBuffer.write(event.character);
      } else if (canDoBackspace()) {
        doBackspace();
      } else if (isEnter()) {
        _codeScanned(_keyboardBuffer.toString());
      } else {
        return KeyEventResult.ignored;
      }
      return KeyEventResult.handled;     
    }
    

    P.S. Which IDE do you use? VS Code can do an autoformat when you save a file or run a project.