Book Image

Mastering Dart

By : Sergey Akopkokhyants
Book Image

Mastering Dart

By: Sergey Akopkokhyants

Overview of this book

Table of Contents (19 chapters)
Mastering Dart
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Methods and operators


Now that we've introduced well-designed classes, we need to discuss methods.

Checking the values of the parameters before using them

The class constructors, methods, mutators (setters), and operators remove some restrictions on the values that must be passed into their parameters .What will happen if an invalid parameter value is passed to a method? One possibility is that the method will fail with a confusing exception or worse it will succeed but with a wrong result. In any case, it's dangerous not check the parameters of a method before using them. The rule here is to check whether the parameter value is valid as soon as possible. The best place to do that is at the beginning of the method.

The Dart VM can work in a developer-friendly checked mode and a speed-obsessed production mode. We usually use the checked mode when developing our applications. One of the benefits of this mode is the dynamic assertion. We should use the assert statement to check whether the parameters of the method are valid before using it. The Dart VM continues the program execution if the Boolean result of the dynamic assertion is true, otherwise stops it. This is shown in the following code:

/**
 * Return sum of [a] and [b].
 * It throws [AssertionError] if any of [a] or [b] equals null
 */
sum(int a, int b) {
  assert(a != null);
  assert(b != null);
  return a + b;
}

Note

The assert statement has no effect when the program executes in the production mode or is compiled with the JavaScript code.

We must check the validity of the parameters stored in the method for later use. Ignoring this can lead to problems later because an error associated with the parameter can be thrown in a completely different place, making it harder to trace its source. This has serious implications, especially in constructors.

Sometimes, it is important to validate the internal state of a class in the method and generate a special error, as shown in the following code. The typical errors are StateError, RangeError, and ArgumentError.

class Car {
  double petrol;

  /**
   * Start engine.
   * That method throws [StateError] if petrol is null
   * or less than 5 liters.
   */
  void startEngine() {
    if (petrol == null || petrol <= 5.0) {
      throw new StateError('Not enough petrol');
    }
  }
}

Here, we have a Car class with the petrol variable and the startEngine method. The startEngine method checks whether there is enough petrol to start the engine; otherwise, it throws an error.

Note

Each time you create a method, think about the restrictions that apply to its parameters.

Well-designed methods

So, now that we've defined well-designed classes, it's time to define well-designed methods. We must remember that methods are part of a class' interface and the following simple rules can make them easier to use and also less error-prone:

  • Choose the right method name. Remember, Dart doesn't support method overloading. Instead, we can have different method names or optional parameters.

  • Use optional named parameters. This helps programmers to use your methods without the need to remember the position of each parameter.

  • Refer to objects in terms of their interfaces over classes as the type of parameters. For example, we have an interface and the class implements that interface. Use the interface as the parameter type of the method instead of a solid one. Don't restrict the solution to a particular implementation.

A car may have the following different types of engines:

// Engine interface
abstract class Engine {
  void start();
}

// Diesel engine
class DieselEngine implements Engine {
  void start() {
    // ...
  }
}

// Carburetor engine
class CarburetorEngine implements Engine {
  void start() {
    // ...
  }
}

// Car
class Car {
  var engine;

  // Car may have any engine
  Car(Engine this.engine);
}

It's better to pass the abstract Engine class as a parameter of the constructor for the car to prevent any problems in future.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.