Deep Dive into Flutter Design Patterns [part 1]

Deep Dive into Flutter Design Patterns [part 1]

What are Design Patterns?

Design Patterns are solutions to software design problems that we encounter in real world application development and blueprints that can be customised to fit our use cases.

Also consists of the 23 Gang of Four (GoF) pattern and are categorised into

  • Creational Design Pattern
  • Structural Design Pattern
  • Behavioural Design Pattern

Creational Design Pattern

The Creational Design Pattern is concerned with the way of creating objects. It provides various object creation mechanism and it can be used when a decision must be made at the time of instantiation of a class.

Factory Design Pattern

The Factory Design pattern comes from one of the creational design pattern that defines an interface for creating an object but allow subclasses to decide which class to instantiate.

How can it be used?

Problem Statement:

You have a company, and that company only take into account skills of developers.

Now they are expanding and want to take into account skills for Quality Assurance Engineers and Finance.

But they can not possibly do it at the moment as all of the code is tightly coupled and is found in the Developer Class.

Solution:

One way to come around this is to have an interface/abstract method (as Dart does not have an interface) where we will be creating a Factory Method.

When doing this, Developers, QA Engineers and Finance, should all be able to implement the Employee interface which declares a method of skill(). And each different employees will return different skill set that they may have.

Flutter example using the Factory Method

Here, what we are trying to do is create a Factory Method that allows us to create cross platform widgets without coupling client code.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

abstract class ButtonFactoryMethod {
  Widget build(VoidCallback onpressed, Widget child);

  factory ButtonFactoryMethod(TargetPlatform platform) {
    switch (platform) {
      case TargetPlatform.android:
        return AndroidActionButton();
      case TargetPlatform.iOS:
        return IosActionButton();
      default:
        return AndroidActionButton();
    }
  }
}

class AndroidActionButton implements ButtonFactoryMethod {
  @override
  Widget build(VoidCallback onpressed, Widget child) {
    return ElevatedButton(onPressed: onpressed, child: child);
  }
}

class IosActionButton implements ButtonFactoryMethod {
  @override
  Widget build(VoidCallback onpressed, Widget child) {
    return CupertinoButton(onPressed: onpressed, child: child);
  }
}

Explanation of the above code:

  • An abstract class called “ButtonFactoryMethod” is created which consists of a Factory Method which will verify what platform we are currently on. If we are on Android, the “AndroidActionButton” class which uses Material UI will be returned or if the platform is IOS, then “IosActionButton” which uses Cupertino will be returned.
  • The abstract class also has a method called build which is being implemented by the classses AndroidActionButton and IosActionButton.
Center(
        child: ButtonFactoryMethod(Theme.of(context).platform).build(
          () {
            print("test");
          },
          Text(Theme.of(context).platform.toString()),
        ),
      )

What the code is doing is above, is that it is checking the platform through the Theme.of(context) and returning the Button based on the platform.

Noting that I made a test on android and ios, see below how it would appear based on the different platforms:

Factory Method to target platform

And that’s it guys! I hope you have a better understanding of Factory Method!

To reach me:

LinkedIn: https://www.linkedin.com/in/faatimah-iz-zaahra-m-0670881a1/

X (previously Twitter): _fz3hra

GitHub: https://github.com/fz3hra

Cheers,

Umme Faatimah-Iz-Zaahra Mujore | Women TechMakers Ambassador | Software Developer