Make methods static if you can

Alexey Inkin
Flutter Senior
Published in
3 min readJan 1, 2022

Take a look at this function:

It is a private method that decorates a child and is used somewhere in this widget.

This method does not use fields of this widget so it can be made static:

Here are the benefits of this change:

Speed

In Dart, as in most programming languages, the keyword this is implemented as a hidden argument to member methods. So in fact, the first example had 2 arguments: this and child with the former one being unused.

Passing an argument is not free, it involves copying some data on each method call. So static methods are just faster.

In this particular case the compiler should optimize it out because this method is private and it is easy to find and fix all calls to it. But for public methods it is harder or impossible. Do not push your luck for compiler optimizations.

Memory usage

Again, as there is an extra argument, an extra 8-bytes variable is created for each method call.

Use in initializer list

Let’s say we want to wrap a child and store it wrapped. Here we pad the child argument and store the new padded widget in the child class field:

Only static methods can be called this way. This is because in Dart you cannot read fields of this before the object is fully initialized. It implies you cannot call member methods in the initializer list as they are potentially allowed to read this.

Static methods are not limited this way as they are just global functions that share the class name for convenience.

Extraction candidate

As this method is independent of this object’s state, it is a good candidate to be extracted to some other utility routine. Not that you should do it right away, but it is good to have this suggestion on your mind if you ever want to. Instance methods are generally harder to spot for extraction.

Disallow overriding

Instance methods can be overridden, and it is a useful tool:

However, sometimes you want to forbid overriding your methods even if they are public. Static methods in Dart cannot be overridden:

This way no-one can change what is printed when A is constructed although staticMethod itself remains public.

Not that you go for static just for this, but it is a useful bonus.

Exceptions to this rule

You expect a change

If you expect to change a private method later so that it does use this, still make it static anyway because you will not have to change the way it is called: it is just _method(), static or not.

But if it is public or you use it outside the class, you may want to make it an instance method in advance. It is because you do not want to change MyClass.method() to object.method() in too many places.

If you are making a package, you should avoid breaking changes the outside code will face so you should think twice if this method will later get to use this.

You need to test this method

Static methods are harder to test because:

  • You cannot mock an object they belong to. It means you mock isolate how they see the world.
  • You cannot pass mocks instead of objects they use. It means you cannot test what they do to these objects.

Still often it’s alright to test the non-static code that calls these methods for them to be covered. Anyway I prioritize comfort. If static means uncertainty or pain, forget static.

You need to allow overriding

As we said, static methods cannot be overridden. So use instance methods if you need to allow overriding the behavior in subclasses.

Assignment

  1. Find methods in your code that should be made static.
  2. Make them static.

--

--

Alexey Inkin
Flutter Senior

Google Developer Expert in Flutter. PHP, SQL, TS, Java, C++, professionally since 2003. Open for consulting & dev with my team. Telegram channel: @ainkin_com