Reusable UI Views
Khi triển khai UI, ta thường đặt tên View theo use case cụ thể — ví dụ TutorView, ProfileView. Điều này khiến View bị tight coupling với một feature duy nhất.
Chương này giới thiệu cách đặt tên và tổ chức View để maximize reusability mà không tăng complexity.
1. Đặt tên View theo bản chất, không theo use case
Phần tiêu đề “1. Đặt tên View theo bản chất, không theo use case”Bạn có một View hiển thị avatar + hai dòng text. Đặt tên gì?
Nếu đang code feature tutor, bạn sẽ gọi là TutorView. Nhưng tên này giới hạn reusability — nó ngụ ý View chỉ dùng cho tutor.
Cách tốt hơn — tách type name khỏi instance name:
// ❌ Type name quá specificlet tutorView = TutorView(displayName: "Caleb", handle: "@CalebGuitar")
// ❌ Khá hơn nhưng vẫn leak use caselet profileView = ProfileView(displayName: "Caleb", handle: "@CalebGuitar")
// ✅ Type name generic — instance name vẫn mô tả contextlet tutorView = ThumbDescriptionView(title: "Caleb", description: "@CalebGuitar")let profileView = ThumbDescriptionView(title: "Caleb", description: "@CalebGuitar")Chú ý: Ta chỉ đổi tên, không thay đổi functionality. Biến vẫn là tutorView, profileView — nhưng type là ThumbDescriptionView.
2. View Primitives
Phần tiêu đề “2. View Primitives”Giống như ta dùng String, Int, Array để build model phức tạp, ta cũng dùng View Primitives để build UI phức tạp.
View Primitives là những View “đơn giản”, không biết về feature nào đang dùng nó:
ThumbDescriptionView— avatar + descriptionTextButton— button có textCalloutView— callout message box
Nhờ type name không gắn với feature cụ thể, các View này có thể sống trong UI library dùng chung.
3. Đừng đặt tên View theo style
Phần tiêu đề “3. Đừng đặt tên View theo style”Ví dụ: Button có viền tròn — đừng gọi là RoundedButton. Vì:
- Nếu design đổi thành sharp corner, tên không còn đúng.
- Style thay đổi thường xuyên, role ổn định hơn.
Thay vào đó, đặt tên theo role: TextButton, ActionButton.
4. Ưu tiên Composition over Smart View
Phần tiêu đề “4. Ưu tiên Composition over Smart View”Thay vì tạo một View “thông minh” xử lý nhiều trường hợp, hãy compose nhiều View đơn giản lại:
// ✅ Compose nhiều simple viewsVStack { ForEach(items) { item in SelectionViewItem(title: item.title, isSelected: item.isSelected) }}Lợi ích:
- Mỗi View nhỏ, dễ hiểu, dễ test.
- Dễ thay đổi layout mà không ảnh hưởng logic bên trong.
- Reuse từng phần riêng lẻ.
5. Tránh over-engineering
Phần tiêu đề “5. Tránh over-engineering”Đừng thêm tính năng “phòng khi cần”. Chỉ build những gì thực sự cần ngay bây giờ.
Nếu sau này cần mở rộng, việc tách nhỏ View từ đầu sẽ giúp mở rộng dễ hơn so với việc sửa một View cồng kềnh.
Kết luận: Tách type name khỏi use case, giữ View đơn giản (primitives), và compose chúng lại. Chỉ cần đổi tên — không cần thêm code — là đã unlock reusability cho toàn bộ app.