Abstract Factory Pattern trong Java

0 0 0

Người đăng: Ông Huy Thắng

Theo Viblo Asia

Abstract Factory là gì?

Abstract Factory là một mẫu thiết kế khởi tạo (creational design pattern) cho phép bạn tạo ra một họ các đối tượng có liên quan với nhau mà không cần chỉ rõ lớp cụ thể (concrete class) của chúng.

Hiểu đơn giản: Nếu Factory Method tạo một đối tượng cụ thể, thì Abstract Factory tạo ra một nhóm (family) các đối tượng liên quan.

(Bạn có thể xem Factory Method trong series trước bài này nhé)

Ví dụ thực tế:

Giả sử bạn xây dựng giao diện cho ứng dụng hỗ trợ nhiều hệ điều hành:

  • Hệ điều hành Windows cần: Button, Checkbox, Scrollbar kiểu Windows
  • Hệ điều hành macOS cần: Button, Checkbox, Scrollbar kiểu macOS

Thay vì tạo từng cái riêng lẻ, bạn dùng Abstract Factory để tạo cả nhóm phù hợp theo hệ điều hành.

 AbstractFactory / \ ConcreteFactoryA ConcreteFactoryB / \ / \
ProductA1 ProductB1 ProductA2 ProductB2
// Abstract Product
interface Button { void render();
} // Concrete Product A
class WindowsButton implements Button { public void render() { System.out.println("Render button in Windows style"); }
} // Concrete Product B
class MacButton implements Button { public void render() { System.out.println("Render button in Mac style"); }
} // Abstract Factory
interface GUIFactory { Button createButton();
} // Concrete Factory A
class WindowsFactory implements GUIFactory { public Button createButton() { return new WindowsButton(); }
} // Concrete Factory B
class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); }
}
// Sử dụng
public class Application { private final Button button; public Application(GUIFactory factory) { this.button = factory.createButton(); } public void render() { button.render(); }
}
// Client Code
public class Main { public static void main(String[] args) { GUIFactory factory; String os = System.getProperty("os.name").toLowerCase(); if (os.contains("mac")) { factory = new MacFactory(); } else { factory = new WindowsFactory(); } Application app = new Application(factory); app.render(); }
}

Áp dụng trong Spring Boot thực tế

Spring Boot có cơ chế Dependency Injection (DI) nên bạn không cần viết new để tạo object như truyền thống. Tuy nhiên, Abstract Factory pattern vẫn hữu ích trong các trường hợp:

Ví dụ thực tế: Hệ thống thanh toán đa kênh (MOMO, ZALO, VNPAY)

Mục tiêu:

Tùy từng kênh thanh toán, tạo ra các object như: PaymentService, RefundService, TransactionValidator tương ứng.

Interface cho dịch vụ:

public interface PaymentService { void pay();
} public interface RefundService { void refund();
}

Triển khai Momo và Zalo

public class MomoPaymentService implements PaymentService { @Override public void pay() { System.out.println("Thanh toán qua MOMO"); }
} public class MomoRefundService implements RefundService { @Override public void refund() { System.out.println("Hoàn tiền qua MOMO"); }
} public class ZaloPaymentService implements PaymentService { @Override public void pay() { System.out.println("Thanh toán qua ZALO"); }
} public class ZaloRefundService implements RefundService { @Override public void refund() { System.out.println("Hoàn tiền qua ZALO"); }
}

Abstract Factory + Implementation

// Định nghĩa Abstract Factory
public interface PaymentFactory { PaymentService createPaymentService(); RefundService createRefundService();
}
// Concreate (bê tông, xây, cụ thể hóa) Factory cho từng loại 
@Component("momo")
public class MomoPaymentFactory implements PaymentFactory { @Override public PaymentService createPaymentService() { return new MomoPaymentService(); } @Override public RefundService createRefundService() { return new MomoRefundService(); }
} @Component("zalo")
public class ZaloPaymentFactory implements PaymentFactory { @Override public PaymentService createPaymentService() { return new ZaloPaymentService(); } @Override public RefundService createRefundService() { return new ZaloRefundService(); }
}

Service sử dụng Factory

@Service
public class PaymentProcessor { private final Map<String, PaymentFactory> factoryMap = new HashMap<>(); @Autowired public PaymentProcessor(List<PaymentFactory> factories) { for (PaymentFactory factory : factories) { Component annotation = factory.getClass().getAnnotation(Component.class); if (annotation != null) { factoryMap.put(annotation.value(), factory); } } } public void process(String channel) { PaymentFactory factory = factoryMap.get(channel); if (factory == null) { throw new IllegalArgumentException("Không hỗ trợ channel: " + channel); } PaymentService paymentService = factory.createPaymentService(); RefundService refundService = factory.createRefundService(); paymentService.pay(); refundService.refund(); }
}

Controller để gọi test

@RestController
@RequestMapping("/pay")
public class PaymentController { private final PaymentProcessor paymentProcessor; @Autowired public PaymentController(PaymentProcessor paymentProcessor) { this.paymentProcessor = paymentProcessor; } @GetMapping("/{channel}") public String handle(@PathVariable String channel) { paymentProcessor.process(channel); return "Processed payment for: " + channel; }
}

Kết quả khi gọi API

GET http://localhost:8080/pay/momo => Console:
Thanh toán qua MOMO Hoàn tiền qua MOMO GET http://localhost:8080/pay/zalo => Console:
Thanh toán qua ZALO Hoàn tiền qua ZALO

Tổng kết

  1. Ưu điểm:
  • Tách rời logic tạo object khỏi client
  • Dễ mở rộng thêm loại sản phẩm mới
  • Giúp unit test dễ hơn
  1. Nhược điểm
  • Code hơi phức tạp nếu chỉ có vài loại
  • Phải tạo nhiều lớp Factory

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thuật toán Matching và ứng dụng trong việc phân loại Lead của Bank

Những ngày tháng 11 sài gòn bỗng đẹp lạ thường, nóng vừa đủ, mát vừa đủ, mọi sóng gió bỗng nhiên dừng lại 1 cách lạ thường. Nếu không có bạn covid thì có lẽ giờ này đang lang thang trên phố sách để đư

0 0 33

- vừa được xem lúc

Signleton Desgin Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu.

0 0 42

- vừa được xem lúc

Design Patterns là gì? Tại sao nó lại là trợ thủ đắc lực của Developers

Design Pattern là một giải pháp chung để giải quyết các vấn đề phổ biến khi thiết kế phần mềm trong lập trình hướng đối tượng OOP. Design pattern là các giải pháp tổng thể đã được tối ưu hóa, được tái

0 0 68

- vừa được xem lúc

Facade Design Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu. . Facade là một mẫu thiết kế thuộc nhóm cấu trúc (Structural Pattern).

0 0 62

- vừa được xem lúc

Adapter Design Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu. . Adapter (wrapper) là một mẫu thiết kế thuộc nhóm Structural Pattern – những mẫu thiết kế cho việc thiết kế cấu trúc.

0 0 54

- vừa được xem lúc

Abstract Factory Design Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu. . Abstract Factory (Kit) là một design pattern thuộc nhóm Creational Pattern Design – những mẫu thiết kế cho việc khởi tạo đối tượng của lớp.

0 0 75