Cây giả: Dùng thụt lề để tạo UI đơn giản hơn
(ratfactor.com)Cây giả: UI đơn giản bằng cách dùng thụt lề
- Khi muốn có danh sách dạng cây trong UI, việc triển khai quan hệ cha-con thường đòi hỏi nhiều công sức và cấu trúc dữ liệu phức tạp.
- Trong cơ sở dữ liệu quan hệ, có thể dùng CTE đệ quy (Common Table Expressions) để lấy dữ liệu có cấu trúc cây.
Dữ liệu có thực sự phải là cấu trúc cây không?
- Cần cân nhắc liệu các mục có thật sự cần quan hệ cha-con hay chỉ cần trông giống như vậy.
- Nếu không cần quan hệ thực sự, có thể lưu cây một cách đơn giản bằng các trường
id,sort,indent,name. - Cách này biểu diễn đúng những gì hiển thị trên màn hình, nên việc tạo giao diện để render và chỉnh sửa danh sách sẽ đơn giản hơn nhiều.
Một ví dụ khác dùng "namespacing"
- Trong HissScript, nếu tên mục có dấu chấm ("."), hệ thống sẽ cắt phần đầu và thụt lề mục để triển khai tính năng namespacing.
- Với trình biên tập game và người chơi, namespacing là quan trọng, nhưng về bản chất đó vẫn chỉ là những cái tên đơn giản.
- Con người thường chỉ cần bề ngoài của cấu trúc cây hơn là một cấu trúc cây thực sự.
Bonus tree-list
- Bằng cách mô phỏng cây thật, có thể lưu đường dẫn và thông tin trong một danh sách phẳng, rồi sắp xếp đường dẫn để duyệt theo chiều sâu hoặc chiều rộng.
- Danh sách phẳng nhìn chung dễ làm việc hơn và phù hợp với máy tính hơn.
Ẩn dụ vật lý
- Khi sắp xếp scrapbook cá nhân, cách một nhóm hoạt động là điều rất rõ ràng với con người, nhưng trên sàn thực tế lại không có cơ chế vật lý nào ép buộc những quan hệ đó.
Lưu ý: không có lời giải phù hợp cho mọi tình huống
- Cần áp dụng kỹ thuật phù hợp với từng kịch bản cụ thể; nếu thực sự cần cấu trúc cây thì hãy dùng cây.
- Nếu cần biết quan hệ thực giữa các mục, đừng dùng các mẹo như thụt lề hoặc đếm ký hiệu trong chuỗi.
GN⁺ nhận định:
- Bài viết này đưa ra cách đơn giản hóa giao diện người dùng trong phát triển phần mềm bằng cách dùng thụt lề trực quan thay cho cấu trúc cây phức tạp.
- Với nhà phát triển, đây là một chiến lược hiệu quả để đơn giản hóa cấu trúc dữ liệu, tiết kiệm thời gian phát triển và giúp bảo trì dễ hơn.
- Bài viết nhấn mạnh rằng cấu trúc cây không phải lúc nào cũng cần thiết; đôi khi chỉ cần một cấu trúc trực quan quen thuộc với người dùng là đủ, từ đó mang lại góc nhìn mới để cải thiện trải nghiệm người dùng.
1 bình luận
Ý kiến Hacker News
Cách tiếp cận đầu tiên, "adjacency list", được xem là "rõ ràng là cách duy nhất".
Cách thứ hai là "một cách đơn giản hơn nhiều", là kiểu mà trước đây chưa từng thấy, và tuy có nhược điểm rõ ràng nhưng trong một số trường hợp vẫn đủ dễ hiểu.
Cách thứ ba, "namespacing", được gọi là "materialized path".
Một cách khác để biểu diễn cây là "nested sets", vốn khá nổi tiếng vào thời kỳ người ta còn xử lý cơ sở dữ liệu quan hệ một cách rất nghiêm túc.
Postgres cung cấp kiểu dữ liệu
ltreecùng các toán tử tìm kiếm, cho phép xử lý cấu trúc cây một cách tự nhiên. Ví dụ, có thể dùngltreeđể tạo bảng, chèn dữ liệu, rồi truy vấn cấu trúc cây bằng các phép tìm kiếm đơn giản.Các giá trị trong cấu trúc này thường là phân cấp của dữ liệu chứ không phải cây hiển thị. Người ta có thể muốn duyệt dữ liệu, hiển thị quan hệ, hoặc sắp xếp lại nó. Việc lưu thông tin trực quan trong cấu trúc dữ liệu bên trong cơ sở dữ liệu có thể là một cách nhìn ngắn hạn.
Có kinh nghiệm khởi nghiệp với một công ty xử lý dữ liệu dạng cây. Có thể chuyển đổi cấu trúc cây thành danh sách thụt lề trong thời gian O(n). Đây từng là một câu hỏi phỏng vấn, và trong cơ sở dữ liệu SQL có nhiều cách để lấy nhanh một phần của cây rồi render nó mà không cần truy vấn đệ quy.
Một cách để lấy dữ liệu cấu trúc cây từ cơ sở dữ liệu quan hệ bằng truy vấn SQL là viết CTE (Common Table Expressions) đệ quy. CTE thực ra khá thú vị, và một khi đã quen thì không có gì phải sợ.
Qua kinh nghiệm, người ta nhận ra rằng thường thì họ không thật sự cần cây, mà chỉ cần bề ngoài của cây. HN và Reddit khác nhau ở điểm này. Trên HN, bình luận con là anh em kế tiếp của bình luận cha, và chỉ cần tăng thêm một mức thụt lề so với bình luận cha để mô phỏng hình thức cây. Trong khi đó, trên Reddit, bình luận con thực sự được lồng bên trong bình luận cha.
Ý tưởng cốt lõi của bài viết là dùng cấu trúc phù hợp với vấn đề. Tuy nhiên, cách triển khai lập luận còn thiếu sót. Không cần CTE để truy xuất cây từ cơ sở dữ liệu; có thể lấy một danh sách phẳng rồi dựng cây ở phía local. Ngoài ra, với cây đủ lớn, việc di chuyển nhánh hoặc thay đổi độ sâu có thể phát sinh chi phí tuyến tính.
Khi mô tả taxonomy hoặc các cấu trúc phân cấp khác, có một cách đơn giản và nhanh là dùng hệ thống tệp cục bộ. Dùng các lệnh
mkdirvàtree, rồi dán kết quả vào email, Slack, pastebin, v.v. để chia sẻ.Nếu chỉ cần lưu/tải, thì một giải pháp đơn giản hơn có thể là serialize dữ liệu theo cách mong muốn, chẳng hạn JSON, rồi lưu dưới dạng chuỗi. Việc dùng dot notation khá giống với cách extension VsCode là Dendron xử lý phân cấp tên.
Vài năm trước cũng từng có một nhận ra tương tự về OpenGL: không cần phải vẽ cả một thế giới đối tượng 3D có cấu trúc phân cấp, mà chỉ cần vẽ một danh sách các tam giác đã được sắp xếp. Điều này khiến nhiều tối ưu hóa trở nên rất dễ thực hiện.