Factory Method là một mẫu thiết kế tạo đối tượng, cho phép các lớp con quyết định lớp nào được khởi tạo. Nó đóng gói logic tạo đối tượng, giúp mở rộng và duy trì mã nguồn dễ dàng hơn.
Vấn đề
Khi thiết kế một ứng dụng, bạn có thể gặp phải tình huống cần tạo đối tượng thuộc một hệ thống lớp cụ thể. Tuy nhiên, lớp cụ thể để khởi tạo có thể không được biết trước cho đến thời điểm chạy. Ngoài ra, bạn muốn tách rời mã khách hàng với các lớp cụ thể, thúc đẩy sự tách rời và linh hoạt.
Giải pháp
Mẫu thiết kế Factory Method đề xuất việc định nghĩa một giao diện hoặc một lớp trừu tượng khai báo một phương thức để tạo đối tượng. Các lớp con sau đó triển khai phương thức này để cung cấp cài đặt cụ thể cho logic tạo đối tượng. Như vậy, mã khách hàng có thể dựa vào giao diện hoặc lớp trừu tượng để tạo đối tượng mà không cần biết lớp cụ thể được khởi tạo.
Cấu trúc
Mẫu thiết kế Factory Method bao gồm các thành phần sau:
- Product: Đây là giao diện hoặc lớp trừu tượng định nghĩa giao diện chung cho tất cả các sản phẩm được tạo bởi factory method.
- ConcreteProduct: Đây là các lớp cụ thể triển khai giao diện Product hoặc mở rộng lớp trừu tượng Product.
- Creator: Đây là giao diện hoặc lớp trừu tượng khai báo factory method. Nó cũng có thể cung cấp một cài đặt mặc định cho việc tạo đối tượng.
- ConcreteCreator: Đây là các lớp cụ thể triển khai giao diện Creator hoặc mở rộng lớp trừu tượng Creator. Chúng ghi đè factory method để cung cấp cài đặt cụ thể cho việc tạo đối tượng.
Ví dụ
Hãy xem xét một ví dụ trong đó chúng ta có một giao diện Shape
và hai lớp cụ thể Circle
và Rectangle
. Chúng ta có thể định nghĩa một giao diện ShapeFactory
với một factory method createShape()
trả về một đối tượng Shape
. Các lớp CircleFactory
và RectangleFactory
sau đó có thể triển khai giao diện ShapeFactory
và cung cấp cài đặt cụ thể cho việc tạo đối tượng Circle
và Rectangle
.
Dưới đây là code minh hoạ bằng typescript
interface Shape {
draw(): void;
}
class Circle implements Shape {
draw() {
console.log("Drawing a circle");
}
}
class Rectangle implements Shape {
draw() {
console.log("Drawing a rectangle");
}
}
interface ShapeFactory {
createShape(): Shape;
}
class CircleFactory implements ShapeFactory {
createShape() {
return new Circle();
}
}
class RectangleFactory implements ShapeFactory {
createShape() {
return new Rectangle();
}
}
// Usage
const circleFactory: ShapeFactory = new CircleFactory();
const circle: Shape = circleFactory.createShape();
circle.draw(); // Output: Drawing a circle
const rectangleFactory: ShapeFactory = new RectangleFactory();
const rectangle: Shape = rectangleFactory.createShape();
rectangle.draw(); // Output: Drawing a rectangle
Nguồn tham khảo: https://refactoring.guru/design-patterns/factory-method