Abstract Factory pattern: Provides interfaces for creating similar objects or objects of the same class, rather than concrete instances.

The model structure

By abstracting the AbstactFactory class and defining the two required methods CreateProductA() and CreateProductB() for this abstract class. A concrete implementation is implemented by inheriting to an instance of the abstract class.

StatefulWidget

In Flutter, the StatefulWidget is an abstract class that defines the necessary method createState().

abstract class StatefulWidget extends Widget {
  /// Initializes [key] for subclasses.
  const StatefulWidget({ Key? key }) : super(key: key);

  @override
  StatefulElement createElement() => StatefulElement(this);

  @protected
  @factory
  State createState(); // ignore: no_logic_in_create_state, this is the original sin
}
Copy the code

This specifies that all statefulWidgets create a State.

The sample code

Next, experiment with this design pattern through an example. We will switch between iOS and Android’s two different styles of build presentation by checking and unchecking the checkbox. The result is shown below



Start by creating three abstract classes for rendering components: IActivityIndicator, ISlider, and ISwitch

abstract class IActivityIndicator {
  Widget render();
}

abstract class ISlider {
  Widget render(double value, ValueSetter<double> onChanged);
}

abstract class ISwitch {
  Widget render(bool value, ValueSetter<bool> onChanged);
}
Copy the code

Abstract class for the whole page:

abstract class IWidgetFactory {
  String getTitle();
  IActivityIndicator createActivityIndicator();
  ISlider createSlider();
  ISwitch createSwitch();
}
Copy the code

Create Widget instance objects in iOS style and Android style respectively.

class MaterialIWidgetsFactory implements IWidgetFactory {
  @override
  IActivityIndicator createActivityIndicator() {
    // TODO: implement createActivityIndicator
    return AndroidActivityIndicator();
  }

  @override
  ISlider createSlider() {
    // TODO: implement createSlider
    return AndroidSlider();
  }

  @override
  ISwitch createSwitch() {
    // TODO: implement createSwitch
    return AndroidSwitch();
  }

  @override
  String getTitle() {
    // TODO: implement getTitle
    return "Android Widgets"; }}class CupertinoWidgetsFactory implements IWidgetFactory {
  @override
  IActivityIndicator createActivityIndicator() {
    // TODO: implement createActivityIndicator
    return IOSActivityIndicator();
  }

  @override
  ISlider createSlider() {
    // TODO: implement createSlider
    return IOSSlider();
  }

  @override
  ISwitch createSwitch() {
    // TODO: implement createSwitch
    return IOSSwitch();
  }

  @override
  String getTitle() {
    // TODO: implement getTitle
    return "iOS Widgets"; }}class AndroidActivityIndicator implements IActivityIndicator {
  @override
  Widget render() {
    // TODO: implement render
    return CircularProgressIndicator(
      backgroundColor: const Color(0xFFECECEC),
      valueColor: AlwaysStoppedAnimation<Color>(Colors.black.withOpacity(0.65))); }}class IOSActivityIndicator implements IActivityIndicator {
  @override
  Widget render() {
    // TODO: implement render
    return constCupertinoActivityIndicator(); }}class AndroidSwitch implements ISwitch {
  @override
  Widget render(bool value, ValueSetter<bool> onChanged) {
    // TODO: implement render
    returnSwitch(value: value, onChanged: onChanged); }}class IOSSwitch implements ISwitch {
  @override
  Widget render(bool value, ValueSetter<bool> onChanged) {
    // TODO: implement render
    returnCupertinoSwitch(value: value, onChanged: onChanged); }}class AndroidSlider implements ISlider {
  @override
  Widget render(double value, ValueSetter<double> onChanged) {
    // TODO: implement render
    returnSlider(value: value, onChanged: onChanged); }}class IOSSlider implements ISlider {
  @override
  Widget render(double value, ValueSetter<double> onChanged) {
    // TODO: implement render
    returnCupertinoSlider(value: value, onChanged: onChanged); }}Copy the code

When used in Page, use abstract classes instead of concrete instances

late IActivityIndicator _activityIndicator;
late ISlider _slider;
late ISwitch _switch;
Copy the code

I won’t post them all because of the amount of code, but if you’re interested, download the sample code for this article, Flutter_Design_Patterns

If you feel that there is a harvest please follow the way to a love three even: 👍 : a praise to encourage. 🌟 : Collect articles, easy to look back! . 💬 : Comment exchange, mutual progress! .