Structural Design Patterns
Structural Pattern là gì? (What Are Structural Patterns?)
Structural patterns xử lý cách các class và object được tổ chức (Compose) thành cấu trúc lớn hơn. Chúng tập trung vào mối quan hệ giữa các thực thể — giúp thay đổi hoặc mở rộng chức năng mà không cần viết lại mọi thứ. Hãy nghĩ về chúng như chất keo (Glue) kết nối kiến trúc của bạn.
Nếu Creational Pattern trả lời "làm sao tạo object?", thì Structural Pattern trả lời "làm sao kết nối chúng với nhau?"
Tại sao quan trọng (Why They Matter)
| Vấn đề | Pattern giải quyết |
|---|---|
| Interface không tương thích cần hoạt động cùng nhau | Adapter |
| Muốn tách abstraction khỏi implementation để cả hai thay đổi độc lập | Bridge |
| Cần xử lý object đơn lẻ và nhóm object theo cùng một cách | Composite |
| Muốn thêm trách nhiệm (Responsibility) cho object động, không cần subclass | Decorator |
| Cần interface đơn giản cho một subsystem phức tạp | Facade |
| Cần chia sẻ state chung cho nhiều object tương tự để tiết kiệm bộ nhớ | Flyweight |
| Cần placeholder để kiểm soát truy cập đến object khác | Proxy |
Miền Coffee Shop (The Coffee Shop Domain)
Tất cả ví dụ trong phần này tiếp tục sử dụng miền Coffee Shop từ Creational Pattern. Chúng ta xây dựng dựa trên model cốt lõi:
// Base product — kế thừa từ Creational Pattern
public abstract class Coffee
{
public string Name { get; init; } = "";
public double Price { get; init; }
public List<string> Ingredients { get; init; } = new();
public CupSize Size { get; init; } = CupSize.Medium;
public override string ToString() =>
$"{Name} ({Size}) — ${Price:F2} [{string.Join(", ", Ingredients)}]";
}
public enum CupSize { Small, Medium, Large }
So sánh các Pattern (Pattern Comparison)
| Pattern | Mục đích (Intent) | Khi nào sử dụng |
|---|---|---|
| Adapter | Chuyển đổi interface này thành interface khác | Tích hợp third-party, wrapper legacy code |
| Bridge | Tách abstraction khỏi implementation | Biến thể đa chiều (nền tảng × định dạng) |
| Composite | Cấu trúc cây (Tree Structure) của object | Menu, file system, sơ đồ tổ chức |
| Decorator | Thêm hành vi động (Dynamic Behavior) | Topping, middleware, streaming wrapper |
| Facade | Interface đơn giản cho subsystem phức tạp | API phức tạp, orchestration service |
| Flyweight | Chia sẻ object tinh granularity hiệu quả | Số lượng lớn object tương tự (game object, ký tự văn bản) |
| Proxy | Kiểm soát truy cập đến object khác | Lazy loading, access control, caching, logging |
Lỗi thường gặp (Common Pitfalls)
- Lạm dụng Adapter: Đừng tạo adapter cho mọi class. Chỉ dùng khi thực sự cần kết nối interface không tương thích.
- Decorator explosion: Quá nhiều decorator khiến debug khó — call stack bị lồng sâu. Giữ chuỗi ngắn và có ý nghĩa.
- Facade trở thành god object: Facade đơn giản hóa truy cập, không sở hữu logic. Nó nên ủy quyền (Delegate), không chứa business logic.
- Tối ưu hóa Flyweight prematurely: Chỉ dùng Flyweight khi đã đo lường được vấn đề bộ nhớ. Đừng tối ưu theo dự đoán.
Chủ đề liên quan (Related Topics)
- SOLID Principles — Structural Pattern dựa nhiều vào OCP và DIP
- Dependency Injection — DI container tổ chức (Compose) object lúc runtime
- Creational Patterns — cách tạo object mà các pattern này tổ chức
- Behavioral Patterns — cách các object đã tổ chức giao tiếp với nhau