Design Pattern in Dart: Builder Pattern

What is the Builder Pattern?

The Builder Pattern is a creational design pattern that separates the construction of a complex object from its representation.

Instead of stuffing all initialization logic into a single constructor with many parameters (which can get messy), we use a builder to construct the object step by step.

Think of it like building a burger at a restaurant:

  • You choose the bread, meat, cheese, and sauces.
  • At the end, you get a complete burger object.

When to Use the Builder Pattern?

  • When creating objects with many optional parameters.
  • When you want to avoid telescoping constructors (constructors with a long list of parameters).
  • When you need step-by-step object creation with clarity and flexibility.

Real-World Example in Dart: Building a Computer

Step 1: The Product (Object to be built)

class Computer {
final String cpu;
final String ram;
final String storage;
final bool hasGraphicsCard;
final bool hasWiFi;

Computer({
required this.cpu,
required this.ram,
required this.storage,
this.hasGraphicsCard = false,
this.hasWiFi = false,
});

@override
String toString() {
return '''
Computer Specs:
CPU: $cpu
RAM: $ram
Storage: $storage
Graphics Card: ${hasGraphicsCard ? "Yes" : "No"}
WiFi: ${hasWiFi ? "Yes" : "No"}
''';
}
}

Step 2: The Builder

class ComputerBuilder {
String? _cpu;
String? _ram;
String? _storage;
bool _hasGraphicsCard = false;
bool _hasWiFi = false;

ComputerBuilder setCPU(String cpu) {
_cpu = cpu;
return this;
}

ComputerBuilder setRAM(String ram) {
_ram = ram;
return this;
}

ComputerBuilder setStorage(String storage) {
_storage = storage;
return this;
}

ComputerBuilder enableGraphicsCard() {
_hasGraphicsCard = true;
return this;
}

ComputerBuilder enableWiFi() {
_hasWiFi = true;
return this;
}

Computer build() {
return Computer(
cpu: _cpu ?? "Unknown CPU",
ram: _ram ?? "Unknown RAM",
storage: _storage ?? "Unknown Storage",
hasGraphicsCard: _hasGraphicsCard,
hasWiFi: _hasWiFi,
);
}
}

Step 3: Client Code (Using the Builder)

void main() {
Computer gamingPC = ComputerBuilder()
.setCPU("Intel i9")
.setRAM("32GB")
.setStorage("1TB SSD")
.enableGraphicsCard()
.enableWiFi()
.build();

Computer officePC = ComputerBuilder()
.setCPU("Intel i5")
.setRAM("16GB")
.setStorage("512GB SSD")
.enableWiFi()
.build();

print(gamingPC);
print(officePC);
}

Example Output:

yamlCopyEditComputer Specs:
  CPU: Intel i9
  RAM: 32GB
  Storage: 1TB SSD
  Graphics Card: Yes
  WiFi: Yes

Computer Specs:
  CPU: Intel i5
  RAM: 16GB
  Storage: 512GB SSD
  Graphics Card: No
  WiFi: Yes

Benefits of Builder Pattern

  • Makes object creation readable and flexible.
  • Avoids huge constructors with too many parameters.
  • Provides a fluent interface for step-by-step construction.
  • Makes objects immutable after construction.

Drawbacks

  • Requires extra boilerplate code (builder classes).
  • Can be overkill for simple objects.

Flutter Use Cases

  • Building UI components step by step (e.g., AlertDialog.Builder style).
  • Constructing API request payloads with many optional fields.
  • Defining configurations for widgets (like ThemeData or TextStyle).

Summary Table

AttributeBuilder Pattern
PurposeStep-by-step construction of objects
Common Use CasesComplex configs, API requests, UI setup
Easy in Dart?Yes, with method chaining
Useful in Flutter?Very common for configs and UI

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