Design Pattern in Dart: Abstract Factory

What is the Abstract Factory Pattern?

The Abstract Factory Pattern is a creational design pattern that lets you create families of related objects without specifying their concrete classes.

In simple terms:
You define an interface for creating families of objects — clients don’t need to know which concrete classes are used — the factory handles that.

It is one level more abstract than Factory Method.


When to Use Abstract Factory?

  • When you need to create families of related objects.
  • When your code needs to be platform-independent.
  • When you want to isolate object creation from usage.

Common in:

  • Cross-platform UI kits (Android/iOS/Desktop)
  • Theme engines (Light/Dark themes)
  • Game engines (2D/3D factories)

Implementing Abstract Factory in Dart

Example: Building UI Kits for Android & iOS


Step 1: Define Abstract Product Interfaces

abstract class Button {
void render();
}

abstract class Checkbox {
void render();
}

Step 2: Create Concrete Products for Each Platform

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 AndroidCheckbox implements Checkbox {
@override
void render() {
print("Rendering Android-style Checkbox");
}
}

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

Step 3: Define Abstract Factory Interface

abstract class WidgetFactory {
Button createButton();
Checkbox createCheckbox();
}

Step 4: Implement Concrete Factories

class AndroidWidgetFactory implements WidgetFactory {
@override
Button createButton() => AndroidButton();

@override
Checkbox createCheckbox() => AndroidCheckbox();
}

class IOSWidgetFactory implements WidgetFactory {
@override
Button createButton() => IOSButton();

@override
Checkbox createCheckbox() => IOSCheckbox();
}

Step 5: Client Code (Platform Independent!)

void main() {
WidgetFactory factory = AndroidWidgetFactory(); // Or IOSWidgetFactory()

Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();

button.render();
checkbox.render();
}

Example Output:

Rendering Android-style Button
Rendering Android-style Checkbox

Explanation:

  • Button and Checkbox are abstract products.
  • AndroidButton / IOSButton, AndroidCheckbox / IOSCheckbox are concrete products.
  • WidgetFactory defines a family of products.
  • AndroidWidgetFactory / IOSWidgetFactory create related objects.
  • Client works with the factory — and stays unaware of the concrete classes being used!

Benefits of Abstract Factory

  • Enforces consistency among related objects (UI kits, themes, etc.).
  • Provides abstraction between object creation and usage.
  • Simplifies code maintenance when adding new platforms.
  • Promotes separation of concerns.

Drawbacks

  • Adds complexity with lots of interfaces and classes.
  • Can lead to rigid architecture if flexibility is not carefully designed.
  • Slightly harder to implement compared to simple Factory Method.

Tips & Best Practices

  • Abstract Factory is very useful when platform-specific code is needed — like Flutter’s own platform channels.
  • Works well for widget factories or plugin adapters.
  • Often combined with Dependency Injection in big apps.

Summary Table

AttributeAbstract Factory Pattern
PurposeFamilies of related objects
Easy in Dart?Yes
Common Use CasesUI kits, Themes, Game engines
Useful in Flutter?Very useful for platform bridging

Để 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