Design Pattern in Dart: Factory Method

What is the Factory Method Pattern?

The Factory Method Pattern is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

In simple terms:
Instead of using new directly, you use a method (factory) to create objects.

When to Use Factory Method?

  • When you want to control the instantiation of classes.
  • When your code needs to work with objects without knowing their concrete types.
  • When you need flexibility in object creation (especially with class hierarchies or dependencies).

Implementing Factory Method in Dart

Approach 1: Using Factory Constructor

dartCopyEditabstract class Button {
  void render();
}

class AndroidButton implements Button {
  @override
  void render() {
    print("Rendering Android-style Button");
  }
}

class IOSButton implements Button {
  @override
  void render() {
    print("Rendering iOS-style Button");
  }
}

class ButtonFactory {
  static Button createButton(String platform) {
    if (platform == "android") {
      return AndroidButton();
    } else if (platform == "ios") {
      return IOSButton();
    } else {
      throw Exception("Unsupported platform");
    }
  }
}

Example Usage:

dartCopyEditvoid main() {
  var button1 = ButtonFactory.createButton("android");
  var button2 = ButtonFactory.createButton("ios");

  button1.render(); // Output: Rendering Android-style Button
  button2.render(); // Output: Rendering iOS-style Button
}

Explanation:

  • Button is an abstract class (or interface).
  • AndroidButton and IOSButton are concrete implementations.
  • ButtonFactory.createButton() is the Factory Method that decides which object to create.

Approach 2: Factory Constructor in a Class

Dart also supports factory constructors built right into the class:

dartCopyEditclass Shape {
  factory Shape(String type) {
    if (type == "circle") return Circle();
    if (type == "square") return Square();
    throw Exception("Unknown shape type");
  }

  void draw() {}
}

class Circle extends Shape {
  @override
  void draw() {
    print("Drawing a Circle");
  }
}

class Square extends Shape {
  @override
  void draw() {
    print("Drawing a Square");
  }
}

void main() {
  var shape1 = Shape("circle");
  var shape2 = Shape("square");

  shape1.draw(); // Drawing a Circle
  shape2.draw(); // Drawing a Square
}

Benefits of Factory Method

  • Centralizes object creation logic.
  • Makes it easier to manage complex object hierarchies.
  • Improves code flexibility and maintainability.
  • Helps with Dependency Injection and testing.

Drawbacks

  • Adds some complexity.
  • Too many factories can lead to scattered object-creation logic.
  • If overused, can be an anti-pattern (“Factory Hell”).

Tips & Best Practices

  • Use factory methods for polymorphic object creation.
  • Combine with Dependency Injection frameworks for advanced scenarios.
  • Useful when working with Flutter platform-specific widgets or plugin adapters.

Summary Table

AttributeFactory Method Pattern
PurposeFlexible object creation
Easy in Dart?Yes (factory constructor supported)
Common Use CasesWidget factories, platform adapters
Useful in Flutter?Absolutely

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Lên đầu trang