Menu
CoddyTech

Hàm khởi tạo nhà máy

Thuộc phần Lập trình hướng đối tượng trong hành trình Dart của Coddy. Bài học 14 trên 110.

Hàm khởi tạo factory là một hàm khởi tạo đặc biệt, không phải lúc nào cũng tạo ra một instance mới. Khác với các hàm khởi tạo thông thường, hàm khởi tạo factory có thể trả về một instance đã có, một kiểu con hoặc thậm chí là null (nếu có thể nhận giá trị null). Bạn khai báo hàm này bằng từ khóa factory.

class Logger {
  static final Logger _instance = Logger._internal();
  
  // Hàm khởi tạo (constructor) có tên riêng tư
  Logger._internal();
  
  // Hàm khởi tạo factory
  factory Logger() {
    return _instance;
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

Trong ví dụ này, hàm khởi tạo factory luôn trả về cùng một instance. Dù bạn gọi Logger() bao nhiêu lần, bạn vẫn nhận được cùng một đối tượng. Mẫu này thường được dùng để triển khai singleton.

Hàm khởi tạo factory khác với hàm khởi tạo thông thường ở một điểm quan trọng: chúng không thể truy cập this vì có thể chúng không tạo instance mới nào. Thay vào đó, chúng phải trả về một đối tượng một cách tường minh:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

Hàm khởi tạo factory rất hữu ích khi bạn cần kiểm soát việc tạo instance, chẳng hạn như trả về các đối tượng đã lưu trong bộ nhớ đệm, triển khai nhóm đối tượng hoặc quyết định kiểu con nào cần khởi tạo dựa trên các tham số đầu vào.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống thông báo dùng hàm khởi tạo factory để tạo các loại thông báo khác nhau dựa trên một chuỗi đầu vào đơn giản.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • notification.dart: Định nghĩa lớp Notification làm lớp cơ sở cho mọi loại thông báo. Lớp này cần có:
    • Một trường String message
    • Một hàm khởi tạo có tên riêng tư Notification._internal để khởi tạo message
    • Một hàm khởi tạo factory Notification(String type, String message) trả về các kiểu thông báo con khác nhau dựa trên tham số type:
      • Nếu type là 'email', hãy trả về một EmailNotification
      • Nếu type là 'sms', hãy trả về một SMSNotification
      • Nếu không, hãy trả về một PushNotification
    • Một phương thức send() in ra Sending: [message]

Trong cùng tệp, hãy tạo ba lớp con kế thừa từ Notification:

  • EmailNotification: Ghi đè send() để in ra Email: [message]
  • SMSNotification: Ghi đè send() để in ra SMS: [message]
  • PushNotification: Ghi đè send() để in ra Push: [message]

Mỗi lớp con cần có một hàm khởi tạo nhận message và truyền giá trị này cho lớp cha bằng super._internal(message).

  • main.dart: Nhập lớp thông báo và tạo ba thông báo bằng hàm khởi tạo factory:
    • Một thông báo email với message 'Welcome!'
    • Một thông báo SMS với message 'Your code is 1234'
    • Một thông báo push với message 'New update available'
    Gọi send() cho từng thông báo theo thứ tự trên.

Đầu ra dự kiến:

Email: Welcome!
SMS: Your code is 1234
Push: New update available

Tự làm thử

import 'notification.dart';

void main() {
  // TODO: Tạo thông báo email với nội dung 'Welcome!'
  
  // TODO: Tạo thông báo SMS với nội dung 'Your code is 1234'
  
  // TODO: Tạo thông báo đẩy với nội dung 'New update available'
  
  // TODO: Gọi send() trên từng thông báo theo đúng thứ tự
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Dart online